blacklight-maps 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|