Импорт широты и долготы в поле местоположения (класс LatLonPointSpatialField) в Solr

Хорошо, я ищу общие рекомендации по импорту файла CSV, содержащего следующие поля

poi_name, latitude, longitude

в ядро ​​Solr (7.x) для выполнения гео-запросов? Как правильно достичь этого? Я старался

  • с использованием bin/postimport создает бесполезную схему, где все поля многозначны. Очевидно, поле местоположения не создается.
  • делаю то же самое, но создаю схему для 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 это расстояние в километрах.

Другие вопросы по тегам