Импорт широты и долготы в поле местоположения (класс 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. Через пользовательский интерфейс не было возможности создать четвертое поле, которое использует другие поля.

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

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

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


person Dan M    schedule 29.10.2018    source источник


Ответы (2)


Во-первых, вам нужно будет определить поле местоположения. Режим без схемы создан для быстрого прототипирования, если вам нужны более конкретные поля (и вы уверены, что поля получают правильный тип в рабочей среде), вам придется настроить их явно. Используйте тип LatLonPointSpatialField для этого , и сделайте его однозначным.

Сначала определите тип поля для использования (это взяты из документации Schema 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.

В старом примере, вероятно, все наоборот: раньше вы отправляли пару latlon, и она индексировалась как два отдельных значения — одно для широты и одно для долготы — под капотом. Вероятно, вы могли бы обойти это, отправив одно значение для каждого, но на самом деле это должно было работать наоборот — отправлять одно значение и индексировать его как два отдельных поля. Поскольку геопространственная поддержка в Lucene (и Solr) только начиналась, уже существующие типы использовались повторно вместо создания более специализированных типов.

person MatsLindh    schedule 29.10.2018
comment
В итоге я создал updateRequestProcessorChain, который сочетает в себе UUID и Location; UUID работает очень хорошо, но процессор определения местоположения выдал мне ОШИБКУ: [doc=2fb5b18a-89c8-4b92-a2a1-98e0e1e81a32] несколько значений, обнаруженных для местоположения не многозначного поля: [22.9308852, 39.3724824], и после того, как я изменил местоположение как многозначное, я получал Ошибка при добавлении поля 'location'='[22.9308852, 39.3724824]' msg=Невозможно разобрать форму заданных форматов \lat,lon\, \xy\ или как WKT, потому что java.text.ParseException: Неизвестное определение формы [22.9308852] Думаете? - person Dan M; 30.10.2018
comment
Я только что понял, что НЕ должен определять местоположение как multivalue, поэтому он не может разобрать его в определение формы. Но если я этого не сделаю, я получу multiple values encountered for non multiValued field location. Я чувствую, что довольно близок к решению здесь, пока я могу объединить два поля :) - person Dan M; 30.10.2018
comment
Проблема была в способе определения клонирования и конкатенации. Я получил эту идею отсюда bryanbende.com/development/ 2015/01/31/ теперь все работает отлично! Огромное спасибо! - person Dan M; 30.10.2018

Просто сделайте вывод и соберите ответ для всех, кто заинтересован, это решение, к которому я пришел, следуя предложению MatsLindh. Контекст: CentOS 7 и Solr 7.5

  • Содержимое файла Sample.csv

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 — расстояние в километрах.

person Dan M    schedule 30.10.2018