sorting - ElasticSearch 深度嵌套排序/评分
问题描述
我的索引中有以下类型的文档,但由于深度嵌套方面,找不到正确排序的方法。
文档示例:
{
"metadatas": [{
"name": "name",
"timeValidity": [{
"since": "1970-01-01T00:00:00.000Z",
"until": "2100-01-01T00:00:00.000Z",
"value_s": "Some random name"
}]
}, {
"name": "riskRatio",
"variants": [{
"value": "3Y",
"timeValidity": [{
"since": "2017-11-17T23:59:59.999Z",
"until": "2017-12-01T23:59:59.998Z",
"value_f": 0.6931
}, {
"since": "2017-12-01T23:59:59.999Z",
"until": "2018-03-01T23:59:59.999Z",
"value_f": 0.7215
}, {
"since": "2018-04-12T00:00:00.000Z",
"until": "2018-04-16T23:59:59.999Z",
"value_f": 0.6849
}]
}]
}]
}
我希望在匹配时进行排序或提升,以便我可以获取由 (asc/desc) 排序的文档,其中包含该嵌套文档metadatas.variants.timeValidity.value_f
中的约束metadata.name=riskRatio
以及该嵌套文档中的约束和metadata.variants.value=3Y
metadata.variants.timeValidity.since <= SOME_DATE
metadata.variants.timeValidity.until >= SOME_DATE
过滤结果很好。我的问题在于事物的排序方面。
script_score
似乎需要指定一个不可能的访问密钥,因为我不知道数组中的位置。sort
不允许我过滤两个属性的范围,因此它也是一个死胡同。所以我最后一次失败的尝试是像这样从下到上:
{
"sort": [{
"metadatas.variants.timeValidity.value_f": {
"mode": "min",
"order": "asc",
"nested": {
"path": "metadatas.variants.timeValidity",
"filter": {
"range": {
"metadatas.variants.timeValidity.since": {
"lte": "2018-01-21T23:59:59.999Z"
},
"metadatas.variants.timeValidity.until": { // forbidden !!
"gte": "2018-01-21T23:59:59.999Z"
}
}
},
"nested": {
"path": "metadatas.variants",
"filter": {
"match": {
"metadatas.variants.value": "3Y"
}
},
"nested": {
"path": "metadatas",
"filter": {
"match": {
"metadatas.name": "riskRatio"
}
}
}
}
}
}
}]
}
我怎样才能正确排序?通过提升排序也可以,但对我来说是一个死胡同。
解决方案
添加explain:true
到查询中对于调试和了解正在发生的事情非常有帮助。
sort
这通过显示它所花费的值的命中为您提供了一个额外的键。
为了能够查询两个范围,必须使用排序部分中的BooleanQuery
。filter
最终正确的查询如下:
{
"sort": [{
"metadatas.variants.timeValidity.value_f": {
"mode": "min",
"order": "asc",
"nested": {
"path": "metadatas",
"filter": {
"match": {
"metadatas.name": "riskRatio"
}
},
"nested": {
"path": "metadatas.variants",
"filter": {
"match": {
"metadatas.variants.value": "3Y"
}
},
"nested": {
"path": "metadatas.variants.timeValidity",
"filter": {
"bool": {
"must": [{
"range": {
"metadatas.variants.timeValidity.since": {
"lte": "2018-01-21T23:59:59.999Z"
}
}
}, {
"range": {
"metadatas.variants.timeValidity.until": {
"gte": "2018-01-21T23:59:59.999Z"
}
}
}]
}
}
}
}
}
}
}]
}
推荐阅读
- javascript - 如果数组中不存在该元素,有什么方法可以添加元素。添加以逗号分隔的元素?
- algorithm - 从列表坐标中找到二维空间中的最小距离坐标
- javascript - rubico 的 `map.pool` 数组实现
- amazon-web-services - AWS CloudWatch 代理失败 - 刷新 EC2 实例标签失败:RequestError:发送请求失败
- react-native - react-navigation:当条件语句为真时,如何隐藏一个特定的 tabBar 图标和标签
- java - 过滤器列表等于参数
- angularjs - 检查调用函数时传递了哪些参数
- javascript - 将 Skulpt 与 React 一起使用
- kubernetes - 是否有“普通”kubernetes 和“气隙”环境的最佳解决方案?
- go - 是否可以更改默认入口点