【问题标题】:ElasticSearch lucene query with subclauses conversion to ES syntax将子句转换为 ES 语法的 ElasticSearch lucene 查询
【发布时间】:2020-10-09 21:32:05
【问题描述】:

我一直在尝试将 lucene 样式查询转换为 ES 查询语法,但我遇到了子条款。例如

(title:history^10 or series:history) and (NOT(language:eng) OR language:eng^5) and (isfree eq 'true' OR (isfree eq 'false' AND owned eq 'abc^5'))

这表明“给我一个匹配'title'或'series'中的历史,但提升标题匹配并且语言不必是英语,但如果是那么提升它并且匹配在哪里免费或不是免费的,请确保它归客户 abc 所有。

我觉得这是一个棘手的查询,但它似乎可以正常工作。将子句转换为 ES 语法让我感到困惑,因为我并没有括号的概念。我想我需要使用布尔查询......我有以下我知道不能正确应用标准的内容 - 它说你应该有(语言:eng OR isFree eq 'true' ORowned:abc)。我似乎无法做出精神上的飞跃来构建包含 NOT 的必须/应该。

请帮忙?

  "query": {
    "bool": {
      "must": [
        {
          "multi_match": {
            "query": "history",
            "fields": [
              "title^10.0",
              "series"              
            ]
          }
        }
      ],
      "should": [
        {
          "term": {
            "language": {
              "value": "eng",
              "boost": 5
            }
          }
        },
        {
          "term": {
            "isFree": {
              "value": true
            }
          }
        },
        {
          "term": {
            "owned": {
              "value": "abc",
              "boost": 5
            }
          }
        }
      ]
    }
  },

【问题讨论】:

    标签: elasticsearch lucene elasticsearch-dsl elasticsearch-query


    【解决方案1】:

    您的查询几乎是正确的,唯一翻译不正确的是查询的这一部分:

    (isfree eq 'true' OR (isfree eq 'false' AND owned eq 'abc^5'))
    

    如果我正确理解您的帖子,这基本上是在说 当“拥有”字段的值为“abc”且价格免费时,将其提升 5 倍。要实现这一点,您需要使用额外的 bool 查询:

    • isFree: true过滤结果
    • 提升与abc 匹配的任何文档的拥有字段
    "bool": {
      "filter": [
        {
          "term": {
            "isFree": {
              "value": false
            }
          }
        }
      ],
      "must": [
        {
          "term": {
            "owned": {
              "value": "abc",
              "boost": 5
            }
          }
        }
      ]
    }
    

    由于这不是为了限制结果集而只提升满足此条件的结果,因此上面的 bool 查询应该放在父 bool 的 should 部分中。最终查询如下所示:

    POST /myindex/_search
    {
      "explain": true,
      "query": {
        "bool": {
          "must": [
            {
              "multi_match": {
                "query": "history",
                "fields": [
                  "title^10",
                  "series"
                ]
              }
            }
          ],
          "should": [
            {
              "term": {
                "language": {
                  "value": "eng",
                  "boost": 5
                }
              }
            },
            {
              "bool": {
                "filter": [
                  {
                    "term": {
                      "isFree": {
                        "value": false
                      }
                    }
                  }
                ],
                "must": [
                  {
                    "term": {
                      "owned": {
                        "value": "abc",
                        "boost": 5
                      }
                    }
                  }
                ]
              }
            }
          ]
        }
      }
    }
    

    注意:使用shouldmust 对内部布尔值产生相同的结果,老实说,我不确定哪个更好,所以我只是随意使用了must

    【讨论】:

    • 谢谢,不是我需要的,但足够接近我可以解决。中的布尔应该有帮助。
    • @GrahamB 这个查询无法解决你需要什么?
    • 只是布尔逻辑的应用与我需要的略有不同,因此拥有的和 isfree 的布尔需要位于包含多重匹配和“应该”的“必须”数组中因为语言子句保持在原来的位置。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-11
    • 1970-01-01
    • 2023-03-30
    • 2018-04-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多