【问题标题】:How to write an at-least-N-terms query together with filter and must_not in Elasticsearch?如何在 Elasticsearch 中与 filter 和 must_not 一起编写至少 N 个术语的查询?
【发布时间】:2019-05-07 16:01:04
【问题描述】:

我要匹配满足以下所有条件的文档:

  1. 作者 == “汤姆”
  2. 状态!=“已删除”
  3. 至少有两个f1-f4 字段与给定值匹配

(所有字段均为keyword

{"size":24,
"query":{
  "bool":{
    "filter":[{"term":{"author":{"value":"tom","boost":1.0}}}],
    "must_not":[{"term":{"status":{"value":"deleted","boost":1.0}}}],
    "should":[
      {"term":{"f1":{"value":"v1","boost":1.0}}},
      {"term":{"f2":{"value":"v2","boost":1.0}}},
      {"term":{"f3":{"value":"v3","boost":1.0}}},
      {"term":{"f4":{"value":"v4","boost":1.0}}}
      ],
      "minimum_should_match":"2",
      "boost":1.0
  }}
}

更新和总结

我上面发布的查询实际上是正确的,但是我的 es 提供程序安装了一个错误的自定义插件来执行“查询优化”,这导致所有“minimum_should_match”被忽略。如果你遇到同样的问题,找不到任何线索,也许你应该检查你是否安装了任何可疑的插件

【问题讨论】:

  • 更新中的一切看起来都很好,我似乎无法复制您的测试用例,您是否有机会将explain: true 添加到您的查询中,看看那里是否有任何可疑之处?由于从字符串类型移动,这些值可能被不正确地索引?

标签: elasticsearch elasticsearch-query


【解决方案1】:

您的查询是正确的,您只需删除"adjust_pure_negative" 标志或将其更改为false。

简而言之,弹性将“忽略”您的所有查询,并在标志设置为 true 的情况下使用must_not 进行过滤。 source

您也可以删除 boost:1,因为默认值为 1,这使得它变得多余。

编辑:我的测试

    await client.index({index: 'test', id: 5, type: 'test', body: {author: "george", status: "deleted", f1: "v1", f2: "v2"}});
    await client.index({index: 'test', id: 6, type: 'test', body: {author: "george", status: "x", f1: "v1",}});
    await client.index({index: 'test', id: 7, type: 'test', body: {author: "george", status: "u", f1: "v1", f2: "v2"}});
    await client.index({index: 'test', id: 8, type: 'test', body: {author: "george", status: "q", f1: "v1", f4: "v4"}});
    await client.index({index: 'test', id: 9, type: 'test', body: {author: "george", status: "1", f3: "v3"}});
    let x = await client.search({
        index: 'test',
        body:
            {"size":24,
                "query":{
                    "bool":{
                        "filter":[{"term":{"author":{"value":"george","boost":1.0}}}],
                        "must_not":[{"term":{"status":{"value":"deleted","boost":1.0}}}],
                        "must":[{
                            "bool":{
                                "should":[
                                    {"term":{"f1":{"value":"v1","boost":1.0}}},
                                    {"term":{"f2":{"value":"v2","boost":1.0}}},
                                    {"term":{"f3":{"value":"v3","boost":1.0}}},
                                    {"term":{"f4":{"value":"v4","boost":1.0}}}],
                                "minimum_should_match":"2",
                                "adjust_pure_negative":false,
                                "boost":1.0}}
                        ],
                        "adjust_pure_negative":false,
                        "boost":1.0}}},
    });

结果: 2 次符合预期:

[
  {
    "_index": "test",
    "_type": "test",
    "_id": "7",
    "_score": 0.5753642,
    "_source": {
      "author": "george",
      "status": "u",
      "f1": "v1",
      "f2": "v2"
    }
  },
  {
    "_index": "test",
    "_type": "test",
    "_id": "8",
    "_score": 0.47000366,
    "_source": {
      "author": "george",
      "status": "q",
      "f1": "v1",
      "f4": "v4"
    }
  }
]

【讨论】:

  • 谢谢。 adjust_pure_negativeboost 由 java rest 高级客户端的 SearchSourceBuilder 生成。我尝试手动将adjust_pure_negative 设置为false,但两个查询的行为仍然保持不变。
  • 我发布了我的测试代码,看看它,如果你发现我的查询和你的查询有什么不同,请告诉我。如果您不能发布索引的映射(我假设它不会是标准的?)以及“误报”文档的示例
  • 我觉得完全一样。请检查更新。即使在最简单的情况下,minimum_should_match 根本不起作用,这真的很奇怪
  • 我终于找到了真正的原因。我公司另一个团队的 ES 提供者安装了一个执行“查询优化”的自定义插件,这导致所有“minimum_should_match”子句被忽略。这是一个严重的错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-05-15
  • 2018-04-06
  • 2020-06-22
  • 1970-01-01
  • 2014-12-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多