Grails 带地理距离过滤器的ElasticSearch MapperParsingException n
我在应用程序中使用这个插件,遇到了一个奇怪的异常 我有一种使用Grails 带地理距离过滤器的ElasticSearch MapperParsingException n,grails,
elasticsearch,Grails,
elasticsearch,我在应用程序中使用这个插件,遇到了一个奇怪的异常 我有一种使用geo_distance过滤器构建请求的方法: class A{ static searchable={ activityLocation geoPoint:true, component:true // some other mappings on some other fields } Location activityLocation // some other fields } a class Loca
geo_distance
过滤器构建请求的方法:
class A{
static searchable={
activityLocation geoPoint:true, component:true
// some other mappings on some other fields
}
Location activityLocation
// some other fields
}
a
class Location{
static searchable = true
String locationName
Double lat
Double lon
}
def activityList=ElasticSearchService.search(
[类型:[域A,域B],
排序:orderBy,顺序:orderAs,大小:(int)maxRes],
{
//blablabla一些工作闭包构建一个工作查询
}
如果(中心平面!=-1){
滤器{
地理距离(
“距离”:搜索半径,
“活动位置”:[lat:(双)centerLat,lon:(双)centerLon]
)
}
}
}
)
每当我尝试将该方法与过滤器一起使用时(即,当我将例如searchRadius
设置为'5km'
和centerLat
/centerLon
以更正坐标时,我的ElasticSearch
节点会发疯,并不断记录以下错误,直到我关闭它:
| Error 2014-08-27 10:31:49076[elasticsearch[Agent Zero][bulk][T#2]]错误索引.索引请求队列-失败的批量项目:MapperParsingException[未能解析];嵌套:ElasticsearchParseException[字段必须为'lat'、'lon'或'geohash';
我尝试在web上查找引发此MappingParserException
的原因,最后我查找了org.elasticsearch.common.geo.GeoUtils
类的异常。显然,引发异常是因为我的lat
和lon
字段不是数字(请参见第372行和第381行)
为什么会发生这种情况?我是否声明我的筛选器错误?我认为您的索引类型映射有问题,为了理解问题所在,您必须发布一些正在索引的数据和类型映射的示例(您可以从主机获取当前映射:port/{index}/\u-mapping/{type})。
尝试按此处所述定义映射:查看3.3.2 GeoPoint,确保正确定义数据点。假设activityLocation的映射为“geo_point”,则无需在坐标前加上“lat”和“lon”,只需发送即可
'activityLocation': [(Double)centerLat,(Double)centerLon]
我认为这个“lat”“lon”前言在早期版本中可能作为geo_点格式得到支持,但从1.0.0开始,我认为它现在还不支持。已经有一段时间了,这个问题让我有点不知所措,但我终于解决了它 我以这种方式映射了以下类:
class A{
static searchable={
activityLocation geoPoint:true, component:true
// some other mappings on some other fields
}
Location activityLocation
// some other fields
}
a
class Location{
static searchable = true
String locationName
Double lat
Double lon
}
有两个问题:
activityLocation
对象时使用root false
选项,因为我希望能够直接搜索它们,这导致我的A
对象包含以下属性(请注意id
字段的存在):
'activityLocation':{'id':'1','locationName':'foo','lat':'42.5464','lon':'65.5647'}
地质点
,因为它不仅仅有lat
和lon
字段
locationName
属性,作为我的activityLocation
对象的一部分,这使它们不是geoPoint
sactivityLocation
的映射更改为以下值:
ActivityLocation{
static searchable = {
only = ['lat', 'lon']
root false
}
String locationName
Double lat
Double lon
}
这解决了我的问题,从那时起我的搜索进展顺利
我必须补充一点,我对文档中关于这一点的内容感到非常困惑,我有点失望,因为我无法映射具有更多属性的地质点
此外,我希望该插件能让我更好地访问ES日志,我花了一段时间才找到错误代码。我确实发现了问题所在,我将发布详细的答案,因为我认为文档不是很清楚。事实证明,这确实是一个映射问题,但文档中指出“longitud的字段”e必须被命名为lon,纬度的字段必须被命名为lat',而不是说不能有任何其他字段。参见我的答案。
I have managed to fix this with few lines of coded added to "DeepDomainClassMarshaller.groovy" and overriding this file.
Previous code:-
if (DomainClassArtefactHandler.isDomainClass(propertyClass)) {
String searchablePropertyName = getSearchablePropertyName()
if (propertyValue.class."$searchablePropertyName") {
// todo fixme - will throw exception when no searchable field.
marshallingContext.lastParentPropertyName = prop.name
marshallResult += [(prop.name): ([id: propertyValue.ident(), 'class': propertyClassName] + marshallingContext.delegateMarshalling(propertyValue, propertyMapping.maxDepth))]
} else {
marshallResult += [(prop.name): [id: propertyValue.ident(), 'class': propertyClassName]]
}
// Non-domain marshalling
}
New Code:-
if (DomainClassArtefactHandler.isDomainClass(propertyClass)) {
String searchablePropertyName = getSearchablePropertyName()
if (propertyValue.class."$searchablePropertyName") {
// todo fixme - will throw exception when no searchable field.
marshallingContext.lastParentPropertyName = prop.name
if(propertyMapping?.isGeoPoint())
marshallResult += [(prop.name): (marshallingContext.delegateMarshalling(propertyValue, propertyMapping.maxDepth))]
else
marshallResult += [(prop.name): ([id: propertyValue.ident(), 'class': propertyClassName] + marshallingContext.delegateMarshalling(propertyValue, propertyMapping.maxDepth))]
} else {
marshallResult += [(prop.name): [id: propertyValue.ident(), 'class': propertyClassName]]
}
// Non-domain marshalling
}
Let me know in case issue still persists.
Note:- I am still using elasticsearch:0.0.3.3.