【问题标题】:Elastic Search Query (a like x and y) or (b like x and y)弹性搜索查询(a 喜欢 x 和 y)或(b 喜欢 x 和 y)
【发布时间】:2017-05-07 05:36:17
【问题描述】:

一些背景信息:在下面的示例中,用户搜索了“HTML CSS”。我从搜索字符串中拆分出每个单词并创建了如下所示的 SQL 查询。

现在我正在尝试创建一个与以下 SQL 查询具有相同逻辑的弹性搜索查询:

SELECT  
     title, description  
FROM `classes` 
WHERE 
    (`title` LIKE '%html%' AND `title` LIKE '%css%') OR 
    (description LIKE '%html%' AND description LIKE '%css%')

目前,已经完成了一半,但似乎还没有做好。

{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "title": "html"
          }
        },
        {
          "term": {
            "title": "css"
          }
        }
      ]
    }
  },
  "_source": [
    "title"
  ],
  "size": 30
}

现在我需要找到如何添加跟随逻辑

OR (description LIKE '%html%' AND description LIKE '%css%')

重要的一点是,我只需要获取标题或中断中包含两个单词的文档。我不想获取只有 1 个单词的文档。

我会在发现更多信息时更新问题。

更新:选择的答案还提供了一种基于该领域提高得分的方法。

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    您可以尝试以下查询。您可以使用should 进行or 操作

    {
     "query": {
      "bool": {
         "should": [
            {
               "bool": {
                  "must": [
                     {
                        "match": {                      // Go for term if your field is analyzed
                           "title": {
                              "query": "html css",
                              "operator": "and",
                              "boost" : 2
                           }
                        }
                     }
                  ]
               }
            },
            {
               "bool": {
                  "must": [
                     {
                        "match": {
                           "description": {
                              "query": "html css",
                              "operator": "and"
                           }
                        }
                     }
                  ]
               }
            }
         ],
         "minimum_number_should_match": 1
      }
     },
      "_source": [
        "title",
        "description"
       ]
    }
    

    希望这会有所帮助!

    【讨论】:

    • 谢谢,它似乎运行良好。我还试图找到一种排序方式,例如标题中的命中比描述中的命中具有更高的 _score。你知道这是否可能吗? :-)
    • 是的,这是可能的。您可以提升title 字段。更新了我的答案。
    • 谢谢你,你很有帮助:-)
    【解决方案2】:

    我觉得在这种情况下最适合使用的查询是multi_match

    multi_match 查询是运行same 查询的便捷方式 多个字段。

    所以你的查询可以写成:

    GET /_search
    {
      "_source": ["title", "description"],
      "query": {
        "multi_match": {
          "query": "html css",
          "fields": ["title^2", "description"],
          "operator":"and"
        }
      }
    }
    
    1. _source 过滤数据集,以便仅数组中提到的字段 将显示在结果中。

    2. ^2 表示用数字 2 提升 title 字段

    3. operator:and 确保查询中的所有 terms 必须匹配 在fields

    【讨论】:

    • 谢谢,但我不得不使用 match_phrase 进行描述,因为它在我的特定用例中提供了更好的结果。所以选择的答案给了我更多的灵活性。下次当我写一个类似的查询时,我会尝试使用 multi_match。感谢你的宝贵时间。我会测试你建议的语法,如果它有效,我也会投票给你的答案。
    【解决方案3】:

    来自 elasticsearch 5.2 文档: 一种选择是使用嵌套数据类型而不是对象数据类型。

    更多详情:https://www.elastic.co/guide/en/elasticsearch/reference/5.2/nested.html

    希望对你有帮助

    【讨论】:

    • 感谢您的尝试,但嵌套用于在文档中存储对象数组。我正在尝试创建一个条件类似于(字段 a,如 x 和 y)或(字段 b,如 x 和 y)的查询。非常不同的用例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多