首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >弹性搜索:如何在获得所需结果后终止多个搜索查询

弹性搜索:如何在获得所需结果后终止多个搜索查询
EN

Stack Overflow用户
提问于 2018-07-04 14:32:10
回答 1查看 609关注 0票数 1

我们有一个名为"Type“的字符串字段的弹性搜索文档。该字段可以具有从"A“到"Z”的不同值。多个文档可以具有相同的类型,即多个文档可以具有"A“类型

我们希望编写一个弹性搜索查询,最多返回这些文档中的30个。根据类型,我们希望输出在不同的组中。例如:

  1. 如果我们有A型文件10份,B型文件15份,C型文件20份,我应该得到A型的全部10份,B型的全部15份,C型的5份。
  2. 如果A型文档为0,B型文档为10,C型文档为15,D型文档为20,则所有10种文档均为B型,C型为15,D型为5。
  3. 最坏的情况是:如果我们没有A类文件.Y和30份Z型文件,我应该得到30份Z型文件。

为此,我编写了一个非常基本的多搜索查询(总共26个查询)。

代码语言:javascript
运行
复制
    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或更多的结果。

请注意:

  1. 在这里,我给出了一个非常简单的条件,即不同的多搜索条件比仅仅基于类型的条件更为复杂。
  2. 我们希望输出多个集合,即类型A、类型B等,所有这些集合都在不同的集合中。(由于这个限制,我们不得不排除无痛脚本选项)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-07-05 21:58:26

看起来,使用sizesort进行一次搜索就可以实现您想要的结果,另外还可以选择使用bool将查询组合为一个。

我能否过早地终止多搜索查询?

不是的。从多搜索文档中我们可以得出这样的结论。它以一定的并发性执行多个搜索请求,并仅在所有查询完成后才发回结果。

它非常类似于散装API,一种轻松执行并行请求的方法。

我能得到匹配的文档,但按自定义的顺序吗?

是的,这就是sort的用途。要实现原始帖子中描述的行为,只需使用以下调用就足够了:

代码语言:javascript
运行
复制
POST /<index_name>/<index_type>/_search?sort=type:asc&size=30

我可以对多个索引进行一次搜索请求,但仍然使用sort

是的,您只需要定义索引列表:

代码语言:javascript
运行
复制
POST /multisearch1,mutlisearch2/<index_type>/_search?sort=type:asc&size=30

或者通配符表达式:

代码语言:javascript
运行
复制
POST /multisearch*/<index_type>/_search?sort=type:asc&size=30

我能按任意顺序排序吗?

是的,例如使用基于脚本的排序。例如,如果您希望按以下顺序查看结果中的typeXCA,您可以编写如下脚本:

代码语言:javascript
运行
复制
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查询,例如:

代码语言:javascript
运行
复制
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"
    }
  }
}

希望这能帮上忙!

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51176058

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档