我需要在Painless脚本中计算弧距,但在这种情况下还没有找到访问geo API的方法,即:
doc[myGeoField].value
API 在这两种情况下,我都无法实例化org.elasticsearch.index.fielddata.ScriptDocValues.GeoPoints
,这样我就可以访问.arcDistance()
方法。
我也无法使用Painless中不是whitelisted的org.elasticsearch.common.geo.GeoUtils
课程。
在脚本中是否还有其他计算弧距的选项?
注意:由于这里解释的原因太长,我有为此用例使用脚本 - 在查询/过滤器中执行此操作不是一种选择。< / em>的
答案 0 :(得分:2)
你想要做的事情似乎是不可能的,因为Elastic的设计选择很差。
我试图做同样的事情(仅限于planeDistance),最后在Painless中实现了planeDistance。
似乎arcDistance和planeDistance等方法莫名其妙地仅在GeoPoints类中实现,而不是在GeoPoint中实现,尽管它更有意义。此外,这些方法only work for the first element位于GeoPoints列表中。
我真的希望有人可以纠正我,虽然我对无痛的经历一直很痛苦。如果你不希望经常改变它,我建议你选择更成熟的东西,比如Java插件。无痛是调试的痛苦,完全缺乏工具,并且没有任何文档。他们也弃用了Groovy和Python,好像无痛是一个不错的替代品。
尽管如此,这里是以英里为单位的距离代码,为了完成(planeDistance的版本,如果你不需要非常准确的距离,请使用它):
double lat1 = location1.lat;
double lon1 = location1.lon;
double lat2 = location2.lat;
double lon2 = location2.lon;
double to_radian = 0.01745329251; /* PI / 180 */
double earth_radius_in_miles = 3959;
double x = (lon2 - lon1) * to_radian * Math.cos((lat2 + lat1) / 2.0 * to_radian);
double y = (lat2 - lat1) * to_radian;
double distanceInMiles = Math.sqrt(x * x + y * y) * earth_radius_in_miles;
答案 1 :(得分:0)
我通过 inner_hits 解决了此问题,请参见以下查询:
mydf.set_index(['a','b','Time'], inplace=True)
# Get Index level values
a = mydf.index.get_level_values('a')
b = mydf.index.get_level_values('b')
t = mydf.index.get_level_values('Time')
# Apply index-based masks
mydf['GRP'] = 'same'
mydf.loc[(a < 5) & (b < 0.5) & (t < day_2), 'GRP'] = 'less'
mydf.loc[(a < 5) & (b > 0.5) & (t > day_1), 'GRP'] = 'more'
mydf.reset_index(drop=False, inplace=True)
mydf
a b Time GRP
0 0 0.550149 2018-10-14 same
1 1 0.889209 2018-10-15 same
2 2 0.845740 2018-10-16 same
3 3 0.340310 2018-10-17 less
4 4 0.613575 2018-10-18 same
5 5 0.229802 2018-10-19 same
6 6 0.013724 2018-10-20 same
7 7 0.810413 2018-10-21 same
8 8 0.897373 2018-10-22 same
9 9 0.175050 2018-10-23 same
下面是一个响应示例:
{
"query": {
"nested": {
"path": "campi",
"query": {
"query_string": {
"query": "*"
}
},
"inner_hits": {
"script_fields": {
"distanceInMeters": {
"script": {
"inline": "!doc['campi.location'].empty ? doc['campi.location'].arcDistance(params.lat, params.lon) : 0",
"lang": "painless",
"params": {
"lon": -43.9207766,
"lat": -19.910621
}
}
}
}
}
}
}
}