FYI - elasticsearch @ v1.5; npm elasticsearch @ 4.0.2
对于我的具体用例,我需要找到五个最近的点,围绕其他点,并计算这五个结果的最大值。出于某种原因,我的下面的查询是返回所有过滤数据的最大值,而不是最近的五个。
到目前为止我的查询:
{}
我的问题是这返回了一个2.99的max_dist,但我可以从命中中清楚地看到它应该只有0.02268!
最后,还有更好的方法来计算最大距离吗?我不需要使用脚本。
见下面的结果:
elasticsearchAPI = Meteor.npmRequire('elasticsearch');
esClient = new elasticsearchAPI.Client({
host: 'myHost'
});
var esQueryObject = {
"index": "ma_homes",
"size": 5,
"body": {
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"geo_distance": {
"LOCATION": {
"lat": 42.5125339,
"lon": -71.06748
},
"distance": "3mi",
"optimize_bbox": "memory"
}
}
}
},
"size": 5,
"sort": [{
"_geo_distance": {
"LOCATION": {
"lat": 42.5125339,
"lon": -71.06748
},
"order": "asc",
"unit": "mi",
"distance_type": "sloppy_arc"
}
}],
"fields": ["F1_V7_2_F1TOWN"],
"aggs": {
"max_dist": {
"max": {
"script": "doc[\u0027LOCATION\u0027].arcDistanceInMiles(lat,lon)",
"params" : {
"lat" : 42.5125339,
"lon" : -71.06748
}
}
}
}
}
}
try {
esClient.search(esQueryObject, function(err, res) {
if ( err ) console.log("err: ", err);
if ( res ) {
console.log("res: ", JSON.stringify(res, null, "\t"));
};
});
}
catch(error) {
console.log("search err: ", error);
};
答案 0 :(得分:2)
这里有两个错误,第二个与第一个强烈相关:
"total": 19428
个文档与您的搜索匹配。你刚回到最近的5。对于这些要点,你需要弄清楚如何限制前5名,或者根本不进行聚合,我建议这是最简单的事情。只需获得前5名,然后获取最后一个值,您就可以获得所需的两个答案。
排序 约束到3英里范围内的距离因为3英里,这很好,但也许你可以通过更快的速度做更好的事情取决于你的需求搜索distance_type
:
{
"size": 5,
"_source": "F1_V7_2_F1TOWN",
"query": {
"filtered": {
"filter": [
{
"geo_distance": {
"LOCATION": {
"lat": 42.5125339,
"lon": -71.06748
},
"distance": "3mi",
"distance_type": "plane"
}
}
]
}
},
"sort": [
{
"_geo_distance": {
"LOCATION": {
"lat": 42.5125339,
"lon": -71.06748
},
"order": "asc",
"unit": "mi",
"distance_type": "sloppy_arc"
}
}
]
}
注意我没有聚合,我使用_source
而不是fields
(fields
用于存储字段,不限制源文档输出),我切换到使用plane
作为过滤器distance_type
,因为它在极点之外的短距离更快;我怀疑太多的家庭将使用两极的距离。对于评分,我将其保留为sloppy_arc,因为它可以在过滤后使用稍微更精确的等式。
我只收到5份文件,其中5份,最后一份将是最远的一份。
作为一个重要的注意事项,ES 2.2+ increased geo performance significantly。