将纬度和经度导入 Solr 中的位置(LatLonPointSpatialField class)字段
Importing latitude and longitude into a location(LatLonPointSpatialField class) field in Solr
好的,我正在寻找有关如何导入包含以下字段的 CSV 文件的一般指南
poi_name, latitude, longitude
进入 Solr (7.x) 核心来执行地理查询?实现这一目标的正确方法是什么?我试过了
- 使用
bin/post
导入会创建一个无用的架构,其中所有字段都是多值的。显然没有创建位置字段。
- 做同样的事情,但通过管理员 UI 为 3 个字段创建一个模式,我得到
"Document is missing mandatory uniqueKey field: id"
。我想获得 id
自动填充随机 uuid
. 的功能
- 最后也是最重要的是如何 "compute" 来自
latitude
和 longitude
的 LatLonPointSpatialField。通过 UI 无法创建利用其他字段的第 4 个字段。
我真的需要麻烦定义一个 DataImportHandler
来执行此操作,还是为所有这些创建一个架构就足够了?
如果纬度和经度已经存在并且我稍后尝试使用位置字段更新架构怎么办?
找不到这样做的好例子,但是有一个旧的例子,如果纬度和经度有预定义的名称,后缀类似于 location_1_coordinate
,location
字段会自动组成location_2_coordinate
这看起来很傻!
首先 - 您必须定义一个位置字段。无模式模式用于快速原型制作,如果您需要更具体的字段(并确保这些字段在生产中获得正确的类型),则必须明确配置它们。为此使用 the LatLonPointSpatialField type,并使其成为单值。
首先定义要使用的字段类型(这些是adopted from the Schema API documentation):
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
另外两个问题可以通过 custom update chain 解决(您在索引文档时提供链的名称作为 update.chain
URL 参数)。
要自动将 GUID 分配给任何索引文档,您可以使用 UUIDUpdateProcessorFactory。将字段名称 (id
) 作为 fieldName
参数。
要将纬度和经度连接到以 ,
作为分隔符的单个字段,您可以使用 ConcatFieldUpdateProcessorFactory. The important thing here is that it concatenates a list of values given for a single valued field into a single value - it does not concatenate two different field names. To fix that we can use a 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)中的地理空间支持刚刚起步,因此重新使用了已经存在的类型,而不是创建更多专用类型。
只需总结并汇总所有感兴趣的人的答案,这是我按照 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
是以千米为单位的距离。
好的,我正在寻找有关如何导入包含以下字段的 CSV 文件的一般指南
poi_name, latitude, longitude
进入 Solr (7.x) 核心来执行地理查询?实现这一目标的正确方法是什么?我试过了
- 使用
bin/post
导入会创建一个无用的架构,其中所有字段都是多值的。显然没有创建位置字段。 - 做同样的事情,但通过管理员 UI 为 3 个字段创建一个模式,我得到
"Document is missing mandatory uniqueKey field: id"
。我想获得id
自动填充随机uuid
. 的功能
- 最后也是最重要的是如何 "compute" 来自
latitude
和longitude
的 LatLonPointSpatialField。通过 UI 无法创建利用其他字段的第 4 个字段。
我真的需要麻烦定义一个 DataImportHandler
来执行此操作,还是为所有这些创建一个架构就足够了?
如果纬度和经度已经存在并且我稍后尝试使用位置字段更新架构怎么办?
找不到这样做的好例子,但是有一个旧的例子,如果纬度和经度有预定义的名称,后缀类似于 location_1_coordinate
,location
字段会自动组成location_2_coordinate
这看起来很傻!
首先 - 您必须定义一个位置字段。无模式模式用于快速原型制作,如果您需要更具体的字段(并确保这些字段在生产中获得正确的类型),则必须明确配置它们。为此使用 the LatLonPointSpatialField type,并使其成为单值。
首先定义要使用的字段类型(这些是adopted from the Schema API documentation):
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
另外两个问题可以通过 custom update chain 解决(您在索引文档时提供链的名称作为 update.chain
URL 参数)。
要自动将 GUID 分配给任何索引文档,您可以使用 UUIDUpdateProcessorFactory。将字段名称 (id
) 作为 fieldName
参数。
要将纬度和经度连接到以 ,
作为分隔符的单个字段,您可以使用 ConcatFieldUpdateProcessorFactory. The important thing here is that it concatenates a list of values given for a single valued field into a single value - it does not concatenate two different field names. To fix that we can use a 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)中的地理空间支持刚刚起步,因此重新使用了已经存在的类型,而不是创建更多专用类型。
只需总结并汇总所有感兴趣的人的答案,这是我按照 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
是以千米为单位的距离。