弹性搜索:如何在获得所需结果后终止多搜索查询
elastic search: how to terminate a multi search query once we get desired result
我们有弹性搜索文档,其中包含一个名为 "Type" 的字符串字段。此字段可以具有从 "A" 到 "Z" 的不同值。多个文档可以具有相同的类型,即多个文档可以具有类型 "A"
我们想编写一个弹性搜索查询,returns 我们最多包含 30 个这样的文档。我们希望输出根据类型位于不同的组中。例如:
- 如果我们有 10 个 A 类文档,15 个 B 类文档,20 个 C 类文档,我应该得到所有 10 个 A 类文档,所有 15 个 B 类文档和 5 个 C 类文档。
- 如果我们有 0 个 A 类文档,10 个 B 类文档,15 个 C 类文档,20 个 D 类文档,我应该得到所有 10 个 B 类文档,15 个 C 类文档和 5 个 D 类文档。
- 最坏情况:如果我们没有任何类型 A ... Y 的文档和 30 个类型 Z 的文档,我应该得到 30 个类型 Z 的文档。
我为此编写了一个非常基本的多搜索查询(总共 26 个查询),即
POST _msearch/
{"index":"<index_name>","type":"<type>"}
{"from":0,"size":30,"query":{"bool":{"must":[{"terms":{"type":["A"]}}]}}}
{"index":"<index_name>","type":"<type>"}
{"from":0,"size":30,"query":{"bool":{"must":[{"terms":{"type":["B"]}}]}}}
...
{"index":"<index_name>","type":"<type>"}
{"from":0,"size":30,"query":{"bool":{"must":[{"terms":{"type":["Z"]}}]}}}
我担心多搜索查询的执行,即对于案例 1 和案例 2,我们得到了足够的输出,即前几个查询的 30 个文档,那么我们为什么要执行其余的多搜索查询?有什么方法可以在我们获得所需数量的结果后停止多搜索查询操作,即一旦我们获得 30 个或更多结果就终止多搜索。
请注意:
- 我在这里给出了非常简单的条件,即不同多搜索的条件比仅基于类型更复杂。
- 我们希望在输出中有多个集合,即类型 A、类型 B 等,都在不同的集合中。 (由于这个限制,我们不得不排除无痛脚本选项)
看起来您可以通过 size
and a sort
, plus optionally using bool
将查询合并为一个搜索来实现您想要的结果。
我可以提前终止多搜索查询吗?
没有。从 Multi Search 的文档我们可以得出结论。它执行多个搜索请求,具有一定的并发级别,并仅在所有查询完成后才返回结果。
它很像 Bulk API,一种轻松执行并行请求的方法。
我能否获得匹配的文档,但顺序是自定义的?
是的,这就是 sort
的用途。要实现原始 post 中描述的行为,使用此调用就足够了:
POST /<index_name>/<index_type>/_search?sort=type:asc&size=30
我可以在多个索引上发出一个搜索请求并仍然使用 sort
吗?
是的,你只需要定义索引列表:
POST /multisearch1,mutlisearch2/<index_type>/_search?sort=type:asc&size=30
或通配符表达式:
POST /multisearch*/<index_type>/_search?sort=type:asc&size=30
我可以按任意顺序排序吗?
是的,例如使用 Script Based Sorting。例如,如果您希望按以下顺序在结果中看到 type
:X
、C
、A
,您可以编写如下脚本:
POST /<index_name>/<type>/_search
{
"size": 30,
"sort": {
"_script": {
"type": "number",
"script": {
"lang": "painless",
"source": """
int r = 1;
if(doc['type'].value == 'X') {
r = 100;
} else if(doc['type'].value == 'C') {
r = 10;
} else if(doc['type'].value == 'A') {
r = 5;
}
r;
"""
},
"order": "desc"
}
}
}
这也适用于多个集合(如上面的查询)。
如果我有一个依赖于 type
值的复杂查询,我可以这样做吗?
是的,没问题,使用bool
查询例如:
POST /<index_name>/<type>/_search
{
"query": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"term": {
"type": "A"
}
},
{
"match": {
"description": "Quick fox"
}
}
]
}
},
{
"bool": {
"must": [
{
"term": {
"type": "X"
}
},
{
"match": {
"description": "Quick bear"
}
}
]
}
}
]
}
},
"size": 30,
"sort": {
"_script": {
"type": "number",
"script": {
"lang": "painless",
"source": """
int r = 1;
if(doc['type'].value == 'X') {
r = 100;
} else if(doc['type'].value == 'C') {
r = 10;
} else if(doc['type'].value == 'A') {
r = 5;
}
r;
"""
},
"order": "desc"
}
}
}
希望对您有所帮助!
我们有弹性搜索文档,其中包含一个名为 "Type" 的字符串字段。此字段可以具有从 "A" 到 "Z" 的不同值。多个文档可以具有相同的类型,即多个文档可以具有类型 "A"
我们想编写一个弹性搜索查询,returns 我们最多包含 30 个这样的文档。我们希望输出根据类型位于不同的组中。例如:
- 如果我们有 10 个 A 类文档,15 个 B 类文档,20 个 C 类文档,我应该得到所有 10 个 A 类文档,所有 15 个 B 类文档和 5 个 C 类文档。
- 如果我们有 0 个 A 类文档,10 个 B 类文档,15 个 C 类文档,20 个 D 类文档,我应该得到所有 10 个 B 类文档,15 个 C 类文档和 5 个 D 类文档。
- 最坏情况:如果我们没有任何类型 A ... Y 的文档和 30 个类型 Z 的文档,我应该得到 30 个类型 Z 的文档。
我为此编写了一个非常基本的多搜索查询(总共 26 个查询),即
POST _msearch/
{"index":"<index_name>","type":"<type>"}
{"from":0,"size":30,"query":{"bool":{"must":[{"terms":{"type":["A"]}}]}}}
{"index":"<index_name>","type":"<type>"}
{"from":0,"size":30,"query":{"bool":{"must":[{"terms":{"type":["B"]}}]}}}
...
{"index":"<index_name>","type":"<type>"}
{"from":0,"size":30,"query":{"bool":{"must":[{"terms":{"type":["Z"]}}]}}}
我担心多搜索查询的执行,即对于案例 1 和案例 2,我们得到了足够的输出,即前几个查询的 30 个文档,那么我们为什么要执行其余的多搜索查询?有什么方法可以在我们获得所需数量的结果后停止多搜索查询操作,即一旦我们获得 30 个或更多结果就终止多搜索。
请注意:
- 我在这里给出了非常简单的条件,即不同多搜索的条件比仅基于类型更复杂。
- 我们希望在输出中有多个集合,即类型 A、类型 B 等,都在不同的集合中。 (由于这个限制,我们不得不排除无痛脚本选项)
看起来您可以通过 size
and a sort
, plus optionally using bool
将查询合并为一个搜索来实现您想要的结果。
我可以提前终止多搜索查询吗?
没有。从 Multi Search 的文档我们可以得出结论。它执行多个搜索请求,具有一定的并发级别,并仅在所有查询完成后才返回结果。
它很像 Bulk API,一种轻松执行并行请求的方法。
我能否获得匹配的文档,但顺序是自定义的?
是的,这就是 sort
的用途。要实现原始 post 中描述的行为,使用此调用就足够了:
POST /<index_name>/<index_type>/_search?sort=type:asc&size=30
我可以在多个索引上发出一个搜索请求并仍然使用 sort
吗?
是的,你只需要定义索引列表:
POST /multisearch1,mutlisearch2/<index_type>/_search?sort=type:asc&size=30
或通配符表达式:
POST /multisearch*/<index_type>/_search?sort=type:asc&size=30
我可以按任意顺序排序吗?
是的,例如使用 Script Based Sorting。例如,如果您希望按以下顺序在结果中看到 type
:X
、C
、A
,您可以编写如下脚本:
POST /<index_name>/<type>/_search
{
"size": 30,
"sort": {
"_script": {
"type": "number",
"script": {
"lang": "painless",
"source": """
int r = 1;
if(doc['type'].value == 'X') {
r = 100;
} else if(doc['type'].value == 'C') {
r = 10;
} else if(doc['type'].value == 'A') {
r = 5;
}
r;
"""
},
"order": "desc"
}
}
}
这也适用于多个集合(如上面的查询)。
如果我有一个依赖于 type
值的复杂查询,我可以这样做吗?
是的,没问题,使用bool
查询例如:
POST /<index_name>/<type>/_search
{
"query": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"term": {
"type": "A"
}
},
{
"match": {
"description": "Quick fox"
}
}
]
}
},
{
"bool": {
"must": [
{
"term": {
"type": "X"
}
},
{
"match": {
"description": "Quick bear"
}
}
]
}
}
]
}
},
"size": 30,
"sort": {
"_script": {
"type": "number",
"script": {
"lang": "painless",
"source": """
int r = 1;
if(doc['type'].value == 'X') {
r = 100;
} else if(doc['type'].value == 'C') {
r = 10;
} else if(doc['type'].value == 'A') {
r = 5;
}
r;
"""
},
"order": "desc"
}
}
}
希望对您有所帮助!