Импорт широты и долготы в поле местоположения (класс LatLonPointSpatialField) в Solr - PullRequest
0 голосов
/ 29 октября 2018

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

poi_name, latitude, longitude

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

  • с использованием импорта bin/post создает бесполезную схему, в которой все поля имеют многозначные значения. Очевидно, поле местоположения не создается.
  • делает то же самое, но создаю схему для 3 полей через интерфейс администратора, и я получаю "Document is missing mandatory uniqueKey field: id". Я хотел бы получить функциональность, в которой id автоматически заполняется случайным uuid.
  • и, наконец, и самое важное, как "вычислить" LatLonPointSpatialField из latitude и longitude. Через интерфейс не было возможности создать 4-е поле, которое использует другие поля.

Мне действительно нужно пройти через задачу определения DataImportHandler, чтобы сделать это, или достаточно создать схему для всего этого?

Что, если широта и долгота уже есть, и я пытаюсь обновить схему полем местоположения позже?

Не могу найти хороший пример для этого, однако есть старый пример, где поле location автоматически составляется, если широта и долгота имеют предопределенные имена с суффиксом, например, location_1_coordinate и location_2_coordinate. глупо!

Ответы [ 2 ]

0 голосов
/ 30 октября 2018

Просто заключите и обобщите ответ для всех, кто заинтересован, это решение, к которому я пришел, следуя предложению 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 - расстояние в километрах.

0 голосов
/ 29 октября 2018

Во-первых - вам нужно определить поле местоположения. Режим без схемы предназначен для быстрого создания прототипов. Если вам нужны более конкретные поля (и убедитесь, что поля получают правильный тип в рабочей среде), вам придется настроить их явно. Для этого используйте тип 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

Две другие проблемы могут быть исправлены с помощью пользовательской цепочки обновлений (вы указываете имя цепочки в качестве параметра URL update.chain при индексации документа).

Чтобы автоматически назначить 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) только начиналась, уже существующие типы использовались повторно вместо создания более выделенных типов.

...