elasticsearch - 按嵌套对象的长度过滤查询。IE。min_child
问题描述
我正在尝试按找到的嵌套对象的数量过滤我的查询。Elastic Search 文档提到使用脚本是一项昂贵的任务,因此我已经着手使用分数来完成,尽管我似乎也无法让脚本正常工作。
这是我的映射:
"mappings": {
"properties": {
"dates" : {
"type" : "nested",
"properties" : {
"rooms" : {
"type" : "integer"
},
"timestamp" : {
"type" : "long"
}
}
},
"doc_id" : {
"type" : "text"
},
"distance" : {
"type" : "integer"
}
...
}
}
以下是一些示例数据:
PUT /test/_doc/1
{
"doc_id": "1",
"distance": 1,
"dates": [
{
"rooms": 1,
"timestamp": 1
},
{
"rooms": 1,
"timestamp": 2
},
...
]
}
我正在按 parentsdistance
字段等进行过滤,并按dates
他们的timestamps
, 和rooms
. 我需要将所有结果过滤为找到的确切数量的嵌套日期。
我试图从这里借钱。
这是我的搜索查询:
GET /test/_search
{
"query" : {
"function_score": {
"min_score": 20,
"boost": 1,
"functions": [
{
"script_score": {
"script": {
"source": "if (_score > 20) { return - 1; } return _score;"
}
}
}
],
"query": {
"bool" : {
"filter": [
{ "range": { "distance": { "lt": 5 }}},
{
"nested": {
"score_mode": "sum",
"boost": 10,
"path": "dates",
"query": {
"bool": {
"filter": [
{ "range": { "dates.rooms": { "gte": 1 } } },
{ "range": { "dates.timestamp": { "lte": 2 }}},
{ "range": { "dates.timestamp": { "gte": 1 }}}
]
}
}
}
}
]
}
}
}
}
}
这将返回所有匹配的结果,但它们的分数均为 0.0,并且没有被找到的嵌套对象的数量过滤。
如果这是正确的解决方案,我怎样才能让它工作?如果没有,我怎样才能在这个搜索中获得一个脚本来完成它?
谢谢!
解决方案
在开始之前,请记住评分功能在 Elastic 6 和 7 之间发生了变化。您可以在此 gist上找到更新的代码示例。
您的问题没有概述您的搜索细节。看代码,好像要检索所有距离小于5的文档,匹配的房间数正好是2。如果正确的话,你提交的代码并没有实现这个。
原因:您的功能分数包含您的主要条件和匹配房间数量的条件(将两者混合起来非常棘手,尽管并非不可能)。为了使事情更简单,将它们隔离起来,使功能分数仅适用于房间数量。
假设您使用的是 elastic 7+,这可能会起作用:
{
"_source": {
"includes": ["*"],
"excludes": ["dates"]
},
"query": {
"bool": {
"must": [
{"range": {"distance": {"lt": 5}}},
{
"function_score": {
"min_score": 20,
"boost": 1,
"score_mode": "multiply",
"boost_mode": "replace",
"functions": [
{
"script_score": {
"script": {
"source": "if (_score > 20) { return 0; } return _score;"
}
}
}
],
"query": {
"nested": {
"path": "date",
"boost": 10,
"score_mode": "sum",
"query": {
"constant_score": {
"boost": 1,
"filter": {
"bool": {
"should": [
{
"bool": {
"must": [
{"term": {"dates.timestamp": 1}},
{"range": {"dates.rooms": {"lt": 5}}}
],
"should": [
{"term": {"dates.other_prop": 1}},
{"term": {"dates.other_prop": 4}}
]
}
},
{
"bool": {
"must": [
{"term": {"dates.timestamp": 2}},
{"range": {"dates.rooms": {"lt": 5}}}
],
"should": [
{"term": {"dates.other_prop": 1}},
{"term": {"dates.other_prop": 3}}
]
}
}
]
}
}
}
}
}
}
}
}
]
}
}
}
推荐阅读
- c# - 如何避免匹配以#开头的数字字符串?
- bash - Bash printf: how to understand zero dot s ("%0.s") syntax
- javascript - 如何在 Jquery 中的两个事件函数之间传递变量?
- postgresql - 如何让我办公室的其他人访问我的数据库?
- python - Python 请求 API 在解码 json 时显示错误
- python - 使用 for 循环遍历 sqlalchemy 数据库进入无限循环
- git - GitHub 向新分支创建拉取请求?
- c# - 无法将“System.Object []”类型的对象转换为我的类 C#
- sql - 如何使用同一组中下一行的数据更新前一条记录
- node.js - 如何在节点 js 中修复“Route.get() 需要回调函数但在 Route 处得到 [object Undefined]”?