Импорт широты и долготы в поле местоположения (класс LatLonPointSpatialField) в Solr
Хорошо, я ищу общие рекомендации по импорту файла CSV, содержащего следующие поля
poi_name, latitude, longitude
в ядро Solr (7.x) для выполнения гео-запросов? Как правильно достичь этого? Я старался
- с использованием
bin/post
import создает бесполезную схему, где все поля многозначны. Очевидно, поле местоположения не создается. - делаю то же самое, но создаю схему для 3 полей через интерфейс администратора, и я получаю
"Document is missing mandatory uniqueKey field: id"
, Я хотел бы получить функциональность, гдеid
автоматически заполняется случайнымuuid
, - и, наконец, и самое важное, как "вычислить" LatLonPointSpatialField из
latitude
а такжеlongitude
, Через пользовательский интерфейс не было возможности создать 4-е поле, которое использует другие поля.
Нужно ли мне идти через проблему определения DataImportHandler
сделать это или достаточно создать схему для всего этого?
Что, если широта и долгота уже есть, и я пытаюсь обновить схему с полем местоположения позже?
Не могу найти хороший пример для этого, однако есть старый пример, где location
поле составляется автоматически, если широта и долгота имеют заранее заданные имена с суффиксом, например location_1_coordinate
а также location_2_coordinate
это кажется глупым!
2 ответа
Сначала - вам нужно определить поле местоположения. Режим без схемы предназначен для быстрого создания прототипов. Если вам нужны более конкретные поля (и убедитесь, что поля получают правильный тип в рабочей среде), вам придется их явно настраивать. Для этого используйте тип LatLonPointSpatialField и сделайте его однозначным.
Сначала определите тип поля для использования (они приняты из документации API схемы):
curl -X POST -H 'Content-type:application/json' --data-binary '{ "add-field-type" : {
"name":"location_type",
"class":"LatLonPointSpecialField"
} ' http://localhost:8983/solr/gettingstarted/schema
Затем добавьте поле с этим типом:
curl -X POST -H 'Content-type:application/json' --data-binary '{
"add-field":{
"name":"location",
"type":"location_type",
"stored":true }
}' http://localhost:8983/solr/gettingstarted/schema
Две другие проблемы могут быть исправлены с помощью пользовательской цепочки обновлений (в качестве update.chain
Параметр URL при индексации документа).
Чтобы автоматически назначить guid для любого проиндексированного документа, вы можете использовать UUIDUpdateProcessorFactory. Дайте название поля (id
) как fieldName
параметр.
Чтобы получить широту и долготу, объединенные в одно поле с ,
в качестве разделителя вы можете использовать ConcatFieldUpdateProcessorFactory. Здесь важно то, что он объединяет список значений, заданных для одного значащего поля, в одно значение - он не объединяет два разных имени поля. Чтобы исправить это, мы можем использовать CloneFieldUpdateProcessor для перемещения значения широты и долготы в отдельное поле.
<updateRequestProcessorChain name="populate-location">
<processor class="solr.CloneFieldUpdateProcessorFactory">
<arr name="source">
<str>latitude</str>
<str>longitude</str>
</arr>
<str name="dest">location</str>
</processor>
<processor class="solr.ConcatFieldUpdateProcessorFactory">
<str name="delimiter">,</str>
</processor>
</updateRequestProcessorChain
Если вы добавите поле местоположения позже и у вас уже есть данные в вашей базе данных, это не сработает. Solr не будет касаться данных, которые уже были проиндексированы, и вам придется переиндексировать, чтобы ваша информация была обработана и проиндексирована правильным образом. Это верно независимо от того, как вы получаете контент в location
поле.
Старый пример, скорее всего, наоборот: раньше вы отправляли латлонную пару, и он индексировался как два отдельных значения - одно для широты и одно для долготы - под капотом. Вероятно, вы могли бы обойти это, отправив по одному значению для каждого, но на самом деле это было сделано для работы наоборот - отправка одного значения и индексация его как двух отдельных полей. Поскольку геопространственная поддержка в Lucene (и Solr) только начиналась, уже существующие типы использовались повторно вместо создания более специализированных типов.
Просто заключите и обобщите ответ для всех, кто заинтересован, это решение, к которому я пришел, следуя предложению MatsLindh. Контекст: CentOS 7 и Solr 7.5
- Sample.csv content
name,lon,lat,
A,22.9308852,39.3724824
B,22.5094530,40.2725792
- соответствующая часть схемы (
managed-schema
файл)
<fieldType name="location" class="solr.LatLonPointSpatialField" docValues="true"/>
...
<field name="lat" type="string" omitTermFreqAndPositions="true" indexed="true" required="true" stored="true"/>
<field name="location" type="location" multiValued="false" stored="true"/>
<field name="lon" type="string" omitTermFreqAndPositions="true" indexed="true" stored="true"/>
solrconfig.xml
<updateRequestProcessorChain name="uuid-location">
<processor class="solr.UUIDUpdateProcessorFactory">
<str name="fieldName">id</str>
</processor>
<processor class="solr.CloneFieldUpdateProcessorFactory">
<str name="source">lat</str>
<str name="dest">location</str>
</processor>
<processor class="solr.CloneFieldUpdateProcessorFactory">
<str name="source">lon</str>
<str name="dest">location</str>
</processor>
<processor class="solr.ConcatFieldUpdateProcessorFactory">
<str name="fieldName">location</str>
<str name="delimiter">,</str>
</processor>
<processor class="solr.LogUpdateProcessorFactory"/>
<processor class="solr.RunUpdateProcessorFactory" />
</updateRequestProcessorChain>
<initParams path="/update/**,/query,/select,/tvrh,/elevate,/spell,/browse">
<lst name="defaults">
<str name="df">_text_</str>
<str name="update.chain">uuid-location</str>
</lst>
</initParams>
и чтобы импортировать файл примера в ядро, запустите следующее в bash
/opt/solr/bin/post -c your_core_name /opt/solr/sample.csv
И если вам интересно, как запросить эти данные, используйте
http://localhost:8983/solr/your_core_name/select?&q=*:*&fq={!geofilt%20sfield=location}&pt=42.27,-74.91&d=1
где pt
это точка широты и долготы d
это расстояние в километрах.