ElasticSearch应该(OR)条件不起作用

时间:2019-07-04 15:35:15

标签: elasticsearch search nosql

阅读下面的修改! 我在此查询中要获取具有 eventType 完全等于“ AgentFoo” OR eventType 的文档完全等于“ CustomerBar” 。我也有一些 must_not 条件和日期范围过滤器:

GET _search
{"size": 100,
 "query": {
   "bool" : {
     minimum_should_match": 1,
     "should": [{ "term": { "eventType.keyword":"AgentFoo" }},
                { "term": { "eventType.keyword":"CustomerBar" }}

     ],
     "must_not" : [{"match": {"correlationId": {"query": "-456-999"}}},
                   {"match": {"correlationId": {"query": "teste"}}},
                   {"match": {"correlationId": {"query": "monitoracao"}}},
                   {"match": {"correlationId": {"query": "abc"}}},
                   {"match": {"correlationId": {"query": "def"}}},
                   {"match": {"correlationId": {"query": "ghi"}}}
                   ],
"filter": {
 "range": { "when": { "gte":"2019-07-02T00:00:00.000Z",
           "lt"  :"2019-12-31T23:59:27.879Z" }}}
   }
}
}

由于某种原因,它仅返回具有 eventType “ CustomerBar”的文档。怎么了elasticSearch版本为6.3.1,事件类型和correlationId结构为:

"eventType": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          }

"correlationId": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          }

谢谢!

EDIT1:

分析仪可能是问题所在,所以我编辑了问题以显示确切的大小写。

EDIT2:

Err ...我刚刚对 eventType 字段进行了排序,发现这两个事件都在显示。另外,添加 minimum_should_match“:1 也很重要。我会接受任何人就这些要点进行详细阐述的答案,因为添加我自己的答案将毫无意义。谢谢。

1 个答案:

答案 0 :(得分:1)

考虑到您的查询,我敢说您在结果中仅获得eventType.keyword“ customer”的原因是,查询的must_not和filter部分仅返回那些内容。

您可以通过删除查询的“应该”部分并运行它来轻松确认这一点。

您还可以确认是否只希望检索具有eventType.keyword值“ agent”或“ customer”的条目吗?

因为我(相信我)知道,this is not what your query is doing。 如果需要其中一个值,则需要在其中添加“ minimum_should_match”:1

最后,您还可以提供correlationId的映射吗? 我相信这也可能是导致您意外结果的原因

根据您对自己的问题的评论进行编辑

因此,您的问题是,您仅检索了前100个结果,并且该子集中的所有条目只有一个eventType,而总结果包括了所有这些。

正如您还指出的,并且我前面已经提到过,minimum_should_match很重要,否则您可能会获得除想要选择的事件类型以外的其他eventType。如果没有此参数,应该的行为就像“更好的匹配”,与您查询的该部分匹配的条目的得分将比其他部分更好,但是与该部分的匹配不是强制性的。

还要意识到的一点是,您的must_not:{"match": {"correlationId": {"query": "-456-999"}}}中的第一个条目很可能没有达到您的期望:它正在过滤掉任何包含“单词” 456或999的correlationId。

您应该阅读analysis上的可用信息。 为了快速总结,分析了一个诸如correlationId之类的文本字段:默认情况下,它根据空格,破折号,点,逗号,...分割成单词。 当您使用match时,对文本字段的查询也是如此。

因此,-456-999被分为456999。 如果这些字词在您查询的relatedId字段中显示为单词,它们将全部匹配,因此将从您的选择中删除。

我还建议使用terms query重写您的查询,以使其更具可读性。

应该用以下内容代替:

"must": {
  "terms": {
    "eventType.keyword": [
      "agent",
      "customer"
    ]
  }
}

如果correlationId也完全匹配,则可以这样写:

"must_not": {
  "terms": {
    "correlationId.keyword": [
        "-456-999",
        "teste",
        "monitoracao",
        "abc",
        "def",
        "ghi"
    ]
  }
}

如果精确匹配不是您所需要的,则需要确保您清楚分析方面,以确认要匹配的类型。实际上,您似乎想要的另一种格式可能与此类似:

{
  "must_not": [
    {
      "match_phrase": {
        "correlationId": "-456-999"
      }
    },
    {
      "match": {
        "correlationId": "teste monitoracao abc def ghi"
      }
    }
  ]
}