弹性搜索-有没有一种方法可以强制文档中可能符合“ must_not”条件的结果?

时间:2019-10-25 01:09:58

标签: elasticsearch

我们运行了大量的文章数据集。我们根据某些关键字,过滤器,范围等进行搜索。我们的查询包含.iloc结构。

我们需要能够强制某些结果以显示符合MUST/SHOULD/MUST_NOT/FILTER标准的结果。

是否有一种方法可以将文档ID强制插入到查询中,从而胜过/覆盖MUST_NOT子句?还是MUST_NOT成为Elastic Search中的王者。

我们尝试在每个MUST_NOT中使用嵌套的布尔查询来强制将文档ID放入结果中,但是什么也没有。下面的示例在MUST/SHOULD块中具有它。

我们尝试将文档ID强制放入SHOULD块中,没有更多的match_phrase等,但是MUST条件仍然胜过MUST_NOT并且没有结果返回。

这是查询的示例。为了简单起见,我删除了聚合。

MUST

在这种情况下,我们正在寻找引用意大利意甲的文件,但排除内容中包含{ "query": { "bool": { "must": [ { "bool": { "must": [], "should": [ { "multi_match": { "query": "Italy", "fields": [ "title", "content^2", "tags" ], "analyzer": "standard", "boost": 1 } }, { "query_string": { "fields": [ "tags" ], "query": "*Italy*", "default_operator": "AND", "minimum_should_match": 1 } } ] } } ], "should": [ { "multi_match": { "query": "Serie A", "fields": [ "title", "content^2", "tags" ], "type": "phrase", "boost": 4 } }, { "multi_match": { "query": "football", "fields": [ "title", "content^2", "tags" ], "boost": 3 } }, { "terms": { "_id": [ "5.4416039680717e+23" ] } } ], "must_not": [ { "match_phrase": { "content": "Cristiano Ronaldo" } }, { "match": { "source.feed.editorialTopics": "AmericanFootball" } } ], "minimum_should_match": 1, "boost": 1 } }, "from": 0, "size": 20 } 的所有文件,但文件ID Cristiano Ronaldo除外,即使该文件ID也必须包括在内内容中是否包含5.4416039680717e+23

结果永远不会返回该文档ID。

我们在做什么错?还是在Elastic Search中没有办法做到这一点?

2 个答案:

答案 0 :(得分:1)

不干扰当前查询逻辑的最简单方法是使用should子句包装所有内容。像这样

{
  "query": {
    "bool": {
      "should": [
        { // --> your current query
          "bool": {
            "must": [
              {
                "bool": {
                  "should": [
                    {
                      "multi_match": {
                        "query": "Italy",
                        "fields": [
                          "title",
                          "content^2",
                          "tags"
                        ],
                        "analyzer": "standard",
                        "boost": 1
                      }
                    },
                    {
                      "query_string": {
                        "fields": [
                          "tags"
                        ],
                        "query": "*Italy*",
                        "default_operator": "AND",
                        "minimum_should_match": 1
                      }
                    }
                  ]
                }
              }
            ],
            "should": [
              {
                "multi_match": {
                  "query": "Serie A",
                  "fields": [
                    "title",
                    "content^2",
                    "tags"
                  ],
                  "type": "phrase",
                  "boost": 4
                }
              },
              {
                "multi_match": {
                  "query": "football",
                  "fields": [
                    "title",
                    "content^2",
                    "tags"
                  ],
                  "boost": 3
                }
              },
              {
                "terms": {
                  "_id": [
                    "5.4416039680717e+23"
                  ]
                }
              }
            ],
            "must_not": [
              {
                "match_phrase": {
                  "content": "Cristiano Ronaldo"
                }
              },
              {
                "match": {
                  "source.feed.editorialTopics": "AmericanFootball"
                }
              }
            ],
            "minimum_should_match": 1,
            "boost": 1
          }
        },
        { // --> the extra logic (else)
          "must": {
            "match_phrase": {
              "content": "Cristiano Ronaldo"
            }
          }
        }
      ]
    }
  },
  "from": 0,
  "size": 20
}

基本上,如果您有一个充满逻辑的查询,并且想说: bring me the results that match either this big query or this smaller one。默认情况下,如果没有其他内容(必须为must_not),则最小匹配项应为1。

答案 1 :(得分:0)

我相信您可以通过将must_not和ID查询放入带有minimum_should_match 1的should子句中来做到这一点:

"should": [
    {
        "must_not": [
            {
                "match_phrase": {
                    "content": "Cristiano Ronaldo"
                }
            },
            {
                "match": {
                    "source.feed.editorialTopics": "AmericanFootball"
                }
            }
        ]
    },
    {
        "terms": {
            "_id": [
                "5.4416039680717e+23"
            ]
        }
    },
],
"minimum_should_match": 1,

这意味着如果它们中的任何一个匹配,您的文档将返回。您必须对此加以处理,以免干扰您的其他应子句(例如,通过使用嵌套的布尔查询?),但是该原理应该起作用