blacklight-maps 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +5 -1
- data/Gemfile +10 -2
- data/README.md +19 -9
- data/app/assets/javascripts/blacklight-maps/blacklight-maps-browse.js +129 -118
- data/app/helpers/blacklight_maps_helper.rb +22 -32
- data/app/views/catalog/_document_maps.html.erb +3 -3
- data/lib/blacklight/maps.rb +2 -0
- data/lib/blacklight/maps/engine.rb +5 -4
- data/lib/blacklight/maps/export.rb +111 -0
- data/lib/blacklight/maps/geometry.rb +35 -0
- data/lib/blacklight/maps/version.rb +1 -1
- data/solr_conf/conf/schema.xml +50 -41
- data/solr_conf/conf/solrconfig.xml +40 -40
- data/spec/features/maps_spec.rb +76 -47
- data/spec/fixtures/sample_solr_documents.yml +39 -21
- data/spec/helpers/blacklight_maps_helper_spec.rb +48 -14
- data/spec/lib/blacklight/maps/export_spec.rb +69 -0
- data/spec/lib/blacklight/maps/geometry_spec.rb +19 -0
- data/spec/spec_helper.rb +1 -1
- metadata +8 -2
data/lib/blacklight/maps.rb
CHANGED
@@ -3,16 +3,17 @@ require 'leaflet-rails'
|
|
3
3
|
require 'leaflet-markercluster-rails'
|
4
4
|
require 'leaflet-sidebar-rails'
|
5
5
|
|
6
|
-
|
7
6
|
module Blacklight
|
8
7
|
module Maps
|
9
8
|
class Engine < Rails::Engine
|
10
|
-
|
11
9
|
# Set some default configurations
|
12
|
-
Blacklight::Configuration.default_values[:view].maps.
|
10
|
+
Blacklight::Configuration.default_values[:view].maps.type = 'bbox'
|
11
|
+
Blacklight::Configuration.default_values[:view].maps.bbox_field = 'place_bbox'
|
12
|
+
Blacklight::Configuration.default_values[:view].maps.placename_coord_field = 'placename_coords'
|
13
13
|
Blacklight::Configuration.default_values[:view].maps.tileurl = "http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
14
14
|
Blacklight::Configuration.default_values[:view].maps.mapattribution = 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>'
|
15
15
|
Blacklight::Configuration.default_values[:view].maps.maxzoom = 8
|
16
|
+
Blacklight::Configuration.default_values[:view].maps.placename_coord_delimiter = '-|-'
|
16
17
|
|
17
18
|
# Add our helpers
|
18
19
|
initializer 'blacklight-maps.helpers' do |app|
|
@@ -29,4 +30,4 @@ module Blacklight
|
|
29
30
|
end
|
30
31
|
end
|
31
32
|
end
|
32
|
-
end
|
33
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
module BlacklightMaps
|
2
|
+
|
3
|
+
# This class provides the ability to export a response document to GeoJSON.
|
4
|
+
# The export is formated as a GeoJSON FeatureCollection, where the features
|
5
|
+
# consist of an array of Point features. For more on the GeoJSON
|
6
|
+
# specification see http://geojson.org/geojson-spec.html.
|
7
|
+
#
|
8
|
+
class GeojsonExport
|
9
|
+
include BlacklightMaps
|
10
|
+
|
11
|
+
# controller is a Blacklight CatalogController object passed by a helper
|
12
|
+
# response_docs is an array of documents passed by a helper
|
13
|
+
def initialize(controller, response_docs)
|
14
|
+
@controller = controller
|
15
|
+
@response_docs = response_docs
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_geojson
|
19
|
+
geojson_docs = { type: 'FeatureCollection',
|
20
|
+
features: build_geojson_features }
|
21
|
+
geojson_docs.to_json
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def blacklight_maps_config
|
27
|
+
@controller.blacklight_config.view.maps
|
28
|
+
end
|
29
|
+
|
30
|
+
def type
|
31
|
+
blacklight_maps_config.type
|
32
|
+
end
|
33
|
+
|
34
|
+
def placename_coord_field
|
35
|
+
blacklight_maps_config.placename_coord_field
|
36
|
+
end
|
37
|
+
|
38
|
+
def placename_coord_delimiter
|
39
|
+
blacklight_maps_config.placename_coord_delimiter
|
40
|
+
end
|
41
|
+
|
42
|
+
def bbox_field
|
43
|
+
blacklight_maps_config.bbox_field
|
44
|
+
end
|
45
|
+
|
46
|
+
def build_geojson_features
|
47
|
+
case type
|
48
|
+
when 'placename_coord'
|
49
|
+
build_placename_coord_features
|
50
|
+
when 'bbox'
|
51
|
+
build_bbox_features
|
52
|
+
else
|
53
|
+
Rails.logger.error("Your Solr field type was not configured with a recognized type, '#{type}' is not yet supported")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Builds the features structure for placename_coord type documents
|
58
|
+
def build_placename_coord_features
|
59
|
+
features = []
|
60
|
+
@response_docs.each do |doc|
|
61
|
+
next if doc[placename_coord_field].nil?
|
62
|
+
doc[placename_coord_field].uniq.each do |loc|
|
63
|
+
values = loc.split(placename_coord_delimiter)
|
64
|
+
features.push(
|
65
|
+
build_point_feature(values[2], values[1],
|
66
|
+
name: values[0],
|
67
|
+
html: render_leaflet_sidebar_partial(doc)))
|
68
|
+
end
|
69
|
+
end
|
70
|
+
features
|
71
|
+
end
|
72
|
+
|
73
|
+
# Builds the features structure for bbox type documents
|
74
|
+
def build_bbox_features
|
75
|
+
features = []
|
76
|
+
@response_docs.each do |doc|
|
77
|
+
next if doc[bbox_field].nil?
|
78
|
+
doc[bbox_field].uniq.each do |loc|
|
79
|
+
lnglat = Geometry::BoundingBox.from_lon_lat_string(loc).find_center
|
80
|
+
features.push(
|
81
|
+
build_point_feature(lnglat[0], lnglat[1],
|
82
|
+
html: render_leaflet_sidebar_partial(doc)))
|
83
|
+
end
|
84
|
+
end
|
85
|
+
features
|
86
|
+
end
|
87
|
+
|
88
|
+
# Render to string the partial for each individual doc
|
89
|
+
def render_leaflet_sidebar_partial(doc)
|
90
|
+
@controller.render_to_string partial: 'catalog/index_maps',
|
91
|
+
locals: { document: SolrDocument.new(doc) }
|
92
|
+
end
|
93
|
+
|
94
|
+
# Build the individual feature which is added to the FeatureCollection.
|
95
|
+
# lng is the longitude of the feature
|
96
|
+
# lat is the latitude of the feature
|
97
|
+
# *args additional arguments can be passed to the feature, these arguments
|
98
|
+
# will be reflected in the 'properties' member.
|
99
|
+
# html: "html string to show up" must be passed for the sidebar to display
|
100
|
+
# list items
|
101
|
+
def build_point_feature(lng, lat, *args)
|
102
|
+
properties = args.extract_options!
|
103
|
+
feature = { type: 'Feature',
|
104
|
+
geometry: {
|
105
|
+
type: 'Point',
|
106
|
+
coordinates: [lng.to_f, lat.to_f] },
|
107
|
+
properties: properties }
|
108
|
+
feature
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module BlacklightMaps
|
2
|
+
|
3
|
+
# Parent class of geospatial objects used in BlacklightMaps
|
4
|
+
class Geometry
|
5
|
+
|
6
|
+
# This class contains Bounding Box objects and methods for interacting with
|
7
|
+
# them.
|
8
|
+
class BoundingBox
|
9
|
+
|
10
|
+
# points is an array containing longitude and latitude values which
|
11
|
+
# relate to the southwest and northeast points of a bounding box
|
12
|
+
# [west, south, east, north] ([swlng, swlat, nelng, nelat]).
|
13
|
+
def initialize(points)
|
14
|
+
@west = points[0].to_f
|
15
|
+
@south = points[1].to_f
|
16
|
+
@east = points[2].to_f
|
17
|
+
@north = points[3].to_f
|
18
|
+
end
|
19
|
+
|
20
|
+
# Returns an array [lng, lat] which is the centerpoint of a BoundingBox.
|
21
|
+
def find_center
|
22
|
+
center = []
|
23
|
+
center[0] = (@west + @east) / 2
|
24
|
+
center[1] = (@south + @north) / 2
|
25
|
+
center
|
26
|
+
end
|
27
|
+
|
28
|
+
# Creates a new bounding box from from a string of points
|
29
|
+
# "-100 -50 100 50" (south west north east)
|
30
|
+
def self.from_lon_lat_string(points)
|
31
|
+
new(points.split(' '))
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/solr_conf/conf/schema.xml
CHANGED
@@ -16,10 +16,10 @@
|
|
16
16
|
limitations under the License.
|
17
17
|
-->
|
18
18
|
|
19
|
-
<!--
|
19
|
+
<!--
|
20
20
|
This is the Solr schema file. This file should be named "schema.xml" and
|
21
21
|
should be in the conf directory under the solr home
|
22
|
-
(i.e. ./solr/conf/schema.xml by default)
|
22
|
+
(i.e. ./solr/conf/schema.xml by default)
|
23
23
|
or located where the classloader for the Solr webapp can find it.
|
24
24
|
|
25
25
|
This example schema is the recommended starting point for users.
|
@@ -51,7 +51,7 @@
|
|
51
51
|
version="1.4" is Solr's version number for the schema syntax and semantics. It should
|
52
52
|
not normally be changed by applications.
|
53
53
|
1.0: multiValued attribute did not exist, all fields are multiValued by nature
|
54
|
-
1.1: multiValued attribute introduced, false by default
|
54
|
+
1.1: multiValued attribute introduced, false by default
|
55
55
|
1.2: omitTermFreqAndPositions attribute introduced, true by default except for text fields.
|
56
56
|
1.3: removed optional field compress feature
|
57
57
|
1.4: default auto-phrase (QueryParser feature) to off
|
@@ -88,7 +88,7 @@
|
|
88
88
|
- If sortMissingLast="false" and sortMissingFirst="false" (the default),
|
89
89
|
then default lucene sorting will be used which places docs without the
|
90
90
|
field first in an ascending sort and last in a descending sort.
|
91
|
-
-->
|
91
|
+
-->
|
92
92
|
|
93
93
|
<!--
|
94
94
|
Default numeric field types. For faster range queries, consider the tint/tfloat/tlong/tdouble types.
|
@@ -115,7 +115,7 @@
|
|
115
115
|
|
116
116
|
<!-- The format for this date field is of the form 1995-12-31T23:59:59Z, and
|
117
117
|
is a more restricted form of the canonical representation of dateTime
|
118
|
-
http://www.w3.org/TR/xmlschema-2/#dateTime
|
118
|
+
http://www.w3.org/TR/xmlschema-2/#dateTime
|
119
119
|
The trailing "Z" designates UTC time and is mandatory.
|
120
120
|
Optional fractional seconds are allowed: 1995-12-31T23:59:59.999Z
|
121
121
|
All other components are mandatory.
|
@@ -130,7 +130,7 @@
|
|
130
130
|
NOW/DAY+6MONTHS+3DAYS
|
131
131
|
... 6 months and 3 days in the future from the start of
|
132
132
|
the current day
|
133
|
-
|
133
|
+
|
134
134
|
Consult the DateField javadocs for more information.
|
135
135
|
|
136
136
|
Note: For faster range queries, consider the tdate type
|
@@ -158,11 +158,11 @@
|
|
158
158
|
|
159
159
|
<!-- The "RandomSortField" is not used to store or search any
|
160
160
|
data. You can declare fields of this type it in your schema
|
161
|
-
to generate pseudo-random orderings of your docs for sorting
|
162
|
-
purposes. The ordering is generated based on the field name
|
161
|
+
to generate pseudo-random orderings of your docs for sorting
|
162
|
+
purposes. The ordering is generated based on the field name
|
163
163
|
and the version of the index, As long as the index version
|
164
164
|
remains unchanged, and the same field name is reused,
|
165
|
-
the ordering of the docs will be consistent.
|
165
|
+
the ordering of the docs will be consistent.
|
166
166
|
If you want different psuedo-random orderings of documents,
|
167
167
|
for the same version of the index, use a dynamicField and
|
168
168
|
change the name
|
@@ -391,13 +391,13 @@
|
|
391
391
|
<filter class="solr.TrimFilterFactory" />
|
392
392
|
<!-- The PatternReplaceFilter gives you the flexibility to use
|
393
393
|
Java Regular expression to replace any sequence of characters
|
394
|
-
matching a pattern with an arbitrary replacement string,
|
394
|
+
matching a pattern with an arbitrary replacement string,
|
395
395
|
which may include back references to portions of the original
|
396
396
|
string matched by the pattern.
|
397
|
-
|
397
|
+
|
398
398
|
See the Java Regular Expression documentation for more
|
399
399
|
information on pattern and replacement string syntax.
|
400
|
-
|
400
|
+
|
401
401
|
http://java.sun.com/j2se/1.5.0/docs/api/java/util/regex/package-summary.html
|
402
402
|
-->
|
403
403
|
<filter class="solr.PatternReplaceFilterFactory"
|
@@ -405,7 +405,7 @@
|
|
405
405
|
/>
|
406
406
|
</analyzer>
|
407
407
|
</fieldType>
|
408
|
-
|
408
|
+
|
409
409
|
<fieldtype name="phonetic" stored="false" indexed="true" class="solr.TextField" >
|
410
410
|
<analyzer>
|
411
411
|
<tokenizer class="solr.StandardTokenizerFactory"/>
|
@@ -419,7 +419,7 @@
|
|
419
419
|
<!--
|
420
420
|
The DelimitedPayloadTokenFilter can put payloads on tokens... for example,
|
421
421
|
a token of "foo|1.4" would be indexed as "foo" with a payload of 1.4f
|
422
|
-
Attributes of the DelimitedPayloadTokenFilterFactory :
|
422
|
+
Attributes of the DelimitedPayloadTokenFilterFactory :
|
423
423
|
"delimiter" - a one character delimiter. Default is | (pipe)
|
424
424
|
"encoder" - how to encode the following value into a playload
|
425
425
|
float -> org.apache.lucene.analysis.payloads.FloatEncoder,
|
@@ -446,12 +446,12 @@
|
|
446
446
|
</fieldType>
|
447
447
|
|
448
448
|
<!-- since fields of this type are by default not stored or indexed,
|
449
|
-
any data added to them will be ignored outright. -->
|
449
|
+
any data added to them will be ignored outright. -->
|
450
450
|
<fieldtype name="ignored" stored="false" indexed="false" multiValued="true" class="solr.StrField" />
|
451
451
|
|
452
452
|
<!-- This point type indexes the coordinates as separate fields (subFields)
|
453
453
|
If subFieldType is defined, it references a type, and a dynamic field
|
454
|
-
definition is created matching *___<typename>. Alternately, if
|
454
|
+
definition is created matching *___<typename>. Alternately, if
|
455
455
|
subFieldSuffix is defined, that is used to create the subFields.
|
456
456
|
Example: if subFieldType="double", then the coordinates would be
|
457
457
|
indexed in fields myloc_0___double,myloc_1___double.
|
@@ -470,13 +470,19 @@
|
|
470
470
|
See http://wiki.apache.org/solr/SpatialSearch
|
471
471
|
-->
|
472
472
|
<fieldtype name="geohash" class="solr.GeoHashField"/>
|
473
|
+
|
474
|
+
<fieldType name="location_rpt" class="solr.SpatialRecursivePrefixTreeFieldType"
|
475
|
+
distErrPct="0.025"
|
476
|
+
maxDistErr="0.000009"
|
477
|
+
units="degrees"
|
478
|
+
/>
|
473
479
|
</types>
|
474
480
|
|
475
481
|
|
476
482
|
<fields>
|
477
483
|
<!-- Valid attributes for fields:
|
478
484
|
name: mandatory - the name for the field
|
479
|
-
type: mandatory - the name of a previously defined type from the
|
485
|
+
type: mandatory - the name of a previously defined type from the
|
480
486
|
<types> section
|
481
487
|
indexed: true if this field should be indexed (searchable or sortable)
|
482
488
|
stored: true if this field should be retrievable
|
@@ -489,9 +495,9 @@
|
|
489
495
|
given field.
|
490
496
|
When using MoreLikeThis, fields used for similarity should be
|
491
497
|
stored for best performance.
|
492
|
-
termPositions: Store position information with the term vector.
|
498
|
+
termPositions: Store position information with the term vector.
|
493
499
|
This will increase storage costs.
|
494
|
-
termOffsets: Store offset information with the term vector. This
|
500
|
+
termOffsets: Store offset information with the term vector. This
|
495
501
|
will increase storage costs.
|
496
502
|
default: a value that should be used if no value is specified
|
497
503
|
when adding a document.
|
@@ -502,7 +508,7 @@
|
|
502
508
|
<field name="timestamp" type="date" indexed="true" stored="true" default="NOW" multiValued="false"/>
|
503
509
|
<!-- default, catch all search field -->
|
504
510
|
<field name="text" type="text" indexed="true" stored="false" multiValued="true"/>
|
505
|
-
|
511
|
+
|
506
512
|
<!-- these display fields are NOT multi-valued -->
|
507
513
|
<field name="marc_display" type="string" indexed="false" stored="true" multiValued="false"/>
|
508
514
|
<field name="title_display" type="string" indexed="false" stored="true" multiValued="false"/>
|
@@ -511,7 +517,7 @@
|
|
511
517
|
<field name="subtitle_vern_display" type="string" indexed="false" stored="true" multiValued="false"/>
|
512
518
|
<field name="author_display" type="string" indexed="false" stored="true" multiValued="false"/>
|
513
519
|
<field name="author_vern_display" type="string" indexed="false" stored="true" multiValued="false"/>
|
514
|
-
|
520
|
+
|
515
521
|
<!-- these fields are also used for display, so they must be stored -->
|
516
522
|
<field name="isbn_t" type="text" indexed="true" stored="true" multiValued="true"/>
|
517
523
|
<field name="language_facet" type="string" indexed="true" stored="true" multiValued="true" />
|
@@ -523,7 +529,7 @@
|
|
523
529
|
<!-- pub_date sort uses new trie-based int fields, which are recommended for any int and are displayable, sortable, and range-quer
|
524
530
|
we use 'tint' for faster range-queries. -->
|
525
531
|
<field name="pub_date_sort" type="tint" indexed="true" stored="true" multiValued="false"/>
|
526
|
-
|
532
|
+
|
527
533
|
<!-- format is used for facet, display, and choosing which partial to use for the show view, so it must be stored and indexed -->
|
528
534
|
<field name="format" type="string" indexed="true" stored="true"/>
|
529
535
|
|
@@ -558,7 +564,7 @@
|
|
558
564
|
<dynamicField name="*_tf" type="tfloat" indexed="true" stored="true"/>
|
559
565
|
<dynamicField name="*_td" type="tdouble" indexed="true" stored="true"/>
|
560
566
|
<dynamicField name="*_tdt" type="tdate" indexed="true" stored="true"/>
|
561
|
-
|
567
|
+
|
562
568
|
<dynamicField name="*_pi" type="pint" indexed="true" stored="true"/>
|
563
569
|
|
564
570
|
<dynamicField name="ignored_*" type="ignored" multiValued="true"/>
|
@@ -572,15 +578,18 @@
|
|
572
578
|
<dynamicField name="*_unstem_search" type="text_general" indexed="true" stored="false" multiValued="true" />
|
573
579
|
<dynamicField name="*spell" type="textSpell" indexed="true" stored="false" multiValued="true" />
|
574
580
|
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
581
|
+
<dynamicField name="*_pt" type="location" stored="true" indexed="true"/>
|
582
|
+
<dynamicField name="*_bbox" type="location_rpt" stored="true" indexed="true" multiValued="true"/>
|
583
|
+
|
584
|
+
<!-- uncomment the following to ignore any fields that don't already match an existing
|
585
|
+
field name or dynamic field, rather than reporting them as an error.
|
586
|
+
alternately, change the type="ignored" to some other type e.g. "text" if you want
|
587
|
+
unknown fields indexed and/or stored by default -->
|
579
588
|
<!--dynamicField name="*" type="ignored" multiValued="true" /-->
|
580
|
-
|
589
|
+
|
581
590
|
</fields>
|
582
591
|
|
583
|
-
<!-- Field to use to determine and enforce document uniqueness.
|
592
|
+
<!-- Field to use to determine and enforce document uniqueness.
|
584
593
|
Unless this field is marked with required="false", it will be a required field
|
585
594
|
-->
|
586
595
|
<uniqueKey>id</uniqueKey>
|
@@ -595,7 +604,7 @@
|
|
595
604
|
is added to the index. It's used either to index the same field differently,
|
596
605
|
or to add multiple fields to the same field for easier/faster searching. -->
|
597
606
|
<!-- Copy Fields -->
|
598
|
-
|
607
|
+
|
599
608
|
<!-- unstemmed fields -->
|
600
609
|
<copyField source="title_t" dest="title_unstem_search"/>
|
601
610
|
<copyField source="subtitle_t" dest="subtitle_unstem_search"/>
|
@@ -607,11 +616,11 @@
|
|
607
616
|
<copyField source="subject_t" dest="subject_unstem_search"/>
|
608
617
|
<copyField source="subject_addl_t" dest="subject_addl_unstem_search"/>
|
609
618
|
<copyField source="subject_topic_facet" dest="subject_topic_unstem_search"/>
|
610
|
-
|
619
|
+
|
611
620
|
<!-- sort fields -->
|
612
621
|
<copyField source="pub_date" dest="pub_date_sort"/>
|
613
|
-
|
614
|
-
|
622
|
+
|
623
|
+
|
615
624
|
<!-- spellcheck fields -->
|
616
625
|
<!-- default spell check; should match fields for default request handler -->
|
617
626
|
<!-- it won't work with a copy of a copy field -->
|
@@ -629,8 +638,8 @@
|
|
629
638
|
<!-- subject spell check; should match fields for subject request handler -->
|
630
639
|
<copyField source="subject_topic_facet" dest="subject_spell"/>
|
631
640
|
<copyField source="subject_t" dest="subject_spell"/>
|
632
|
-
<copyField source="subject_addl_t" dest="subject_spell"/>
|
633
|
-
|
641
|
+
<copyField source="subject_addl_t" dest="subject_spell"/>
|
642
|
+
|
634
643
|
<!-- OpenSearch query field should match request handler search fields -->
|
635
644
|
<copyField source="title_t" dest="opensearch_display"/>
|
636
645
|
<copyField source="subtitle_t" dest="opensearch_display"/>
|
@@ -641,19 +650,19 @@
|
|
641
650
|
<copyField source="author_addl_t" dest="opensearch_display"/>
|
642
651
|
<copyField source="subject_topic_facet" dest="opensearch_display"/>
|
643
652
|
<copyField source="subject_t" dest="opensearch_display"/>
|
644
|
-
<copyField source="subject_addl_t" dest="opensearch_display"/>
|
653
|
+
<copyField source="subject_addl_t" dest="opensearch_display"/>
|
645
654
|
|
646
655
|
|
647
|
-
<!-- Above, multiple source fields are copied to the [text] field.
|
648
|
-
Another way to map multiple source fields to the same
|
649
|
-
destination field is to use the dynamic field syntax.
|
656
|
+
<!-- Above, multiple source fields are copied to the [text] field.
|
657
|
+
Another way to map multiple source fields to the same
|
658
|
+
destination field is to use the dynamic field syntax.
|
650
659
|
copyField also supports a maxChars to copy setting. -->
|
651
|
-
|
660
|
+
|
652
661
|
<!-- <copyField source="*_t" dest="text" maxChars="3000"/> -->
|
653
662
|
|
654
663
|
<!-- copy name to alphaNameSort, a field designed for sorting by name -->
|
655
664
|
<!-- <copyField source="name" dest="alphaNameSort"/> -->
|
656
|
-
|
665
|
+
|
657
666
|
|
658
667
|
<!-- Similarity is the scoring routine for each document vs. a query.
|
659
668
|
A custom similarity may be specified here, but the default is fine
|