ElasticSearch lucene 查询,子句转换为 ES 语法

ElasticSearch lucene query with subclauses conversion to ES syntax

我一直在尝试将 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'))

这表明 "get me a match for history in 'title' or 'series' but boost the title match AND where the language doesn't have to be english, but if if is then boost it AND where the match is free or where it isn't free then make sure it's owned by customer abc"。

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

请帮忙?

  "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
            }
          }
        }
      ]
    }
  },

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

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

如果我对你的 post 的理解是正确的,这基本上是说 将 'owned' 字段的值为 'abc' 并且价格提高了五倍免费。要实现这一点,您需要使用一个额外的 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 会为内部 bool 产生相同的结果,老实说,我不确定使用哪个更好,所以我只是随意使用 must