【问题标题】:How to write the elastic search query for this?如何为此编写弹性搜索查询?
【发布时间】:2020-10-11 04:39:48
【问题描述】:

我们如何编写具有以下条件的查询:

  1. 状态不得为“非活动”
  2. searchString 必须是“some_String”
  3. adsPurchased 必须是真实的
  4. productCost 下必须有“Product 1”
  5. 根据“产品 1”的成本对其进行排序

数据结构:

 "名称": "罗斯",
  “状态”:“活动”,
  “adsPurchased”:是的,
  "searchString": "some_tring",
  “产品成本”:[
    {
      “产品”:“产品 1”,
      “成本”:“50.0”
    },
    {
      “产品”:“产品 2”,
      “成本”:“80.0”
    }
  ]
}

{
  “名称”:“钱德勒”,
  “状态”:“非活动”,
  “adsPurchased”:是的,
  "searchString": "some_String",
  “产品成本”:[
    {
      “产品”:“产品 1”,
      “成本”:“60.0”
    },
    {
      “产品”:“产品 4”,
      “成本”:“800.0”
    }
  ]
}

{
  “名字”:“乔伊”,
  “状态”:“活动”,
  “adsPurchased”:是的,
  "searchString": "some_tring",
  “产品成本”:[
    {
      “产品”:“产品 1”,
      “成本”:“30.0”
    },
    {
      “产品”:“产品 5”,
      “成本”:“90.0”
    }
  ]
}


所以,我应该得到罗斯和乔伊

【问题讨论】:

  • 你使用的映射是什么?

标签: elasticsearch elasticsearch-dsl elasticsearch-query


【解决方案1】:

映射:

{
  "mappings": {
    "properties": {
      "name": {
        "type": "text"
      },
      "status": {
        "type": "text"
      },
      "adsPurchased": {
        "type": "boolean"
      },
      "searchString": {
        "type": "text"
      },
      "productCost": {
        "type": "nested",
        "properties": {
          "product": {
            "type": "text"
          },
          "cost": {
            "type": "integer"
          }
        }
      }
    }
  }
}

搜索查询:

{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "adsPurchased": true    -->adsPurchased MUST to be true
          }
        },
        {
          "match": {
            "searchString": "some_tring"    -->searchString MUST be "some_tring"
          }
        },
        {
          "nested": {
            "path": "productCost",
            "query": {
              "bool": {
                "must": [           -->must have "Product 1" under productCost
                  {
                    "match": {
                      "productCost.product": "Product 1"  
                    }
                  }
                ]
              }
            }
          }
        }
      ],
      "must_not": [
        {
          "match": {
            "status": "INACTIVE"    -->status MUST NOT be "INACTIVE"              
            }
        }
      ]
    }
  },
  "sort": [                                 -->Sort them based on cost
    {
      "productCost.cost": {
        "order": "asc",
        "nested_path": "productCost"
      }
    }
  ]
}

搜索结果:

"hits": [
      {
        "_index": "foo3",
        "_type": "_doc",
        "_id": "2",
        "_score": null,
        "_source": {
          "name": "joey",
          "status": "ACTIVE",
          "adsPurchased": true,
          "searchString": "some_tring",
          "productCost": [
            {
              "product": "Product 1",
              "cost": "30.0"
            },
            {
              "product": "Product 5",
              "cost": "90.0"
            }
          ]
        },
        "sort": [
          30
        ]
      },
      {
        "_index": "foo3",
        "_type": "_doc",
        "_id": "1",
        "_score": null,
        "_source": {
          "name": "Ross",
          "status": "ACTIVE",
          "adsPurchased": true,
          "searchString": "some_tring",
          "productCost": [
            {
              "product": "Product 1",
              "cost": "50.0"
            },
            {
              "product": "Product 2",
              "cost": "80.0"
            }
          ]
        },
        "sort": [
          50
        ]
      }
    ]

在搜索结果中,您会得到想要的结果,即 Ross 和 joey

想了解更多嵌套排序,可以参考这个官方documentation,嵌套查询参考this

【讨论】:

  • @Asraar Wani 你有没有机会仔细阅读我的回答,期待得到你的反馈,如果有帮助,请不要忘记点赞并接受:)
  • 非常感谢。我是弹性搜索的新手,我几乎挣扎了一个小时,我无法编写这个查询。再次感谢!!
  • 无论如何,必须对排序选项进行一些调整:"sort": [ { "productCost.cost": { "order": "asc", "nested_path": "productCost", "nested_filter": { "term": { "productCost.product": "Product 1" } } } } ]
  • @Asraar Wani 感谢您接受答案,如果您也可以投票给答案,那就太好了:)
  • 完成!再次感谢您
【解决方案2】:

filtersort 中需要类似 mustmust_not 的内容,我使用了过滤上下文,因为它更快,如果你可以使用查询上下文需要。查看查询和过滤上下文的区别:https://www.elastic.co/guide/en/elasticsearch/reference/current/query-filter-context.html

GET /your_index_name/_search
{
   "query" : {
      "constant_score" : { 
         "filter" : {
            "bool" : {
              "must" : [
                 { "term" : {"searchString" : "some_String"}}, 
                 { "term" : {"adsPurchased" : true}},
                 { "nested":
                      {
                        "path": "parent","query": {
                           "match": {"productCost.cost": "Product 1"}
                         }
                      }
                 }
              ],
              "must_not" : {
                 "term" : {"status" : "INACTIVE"} 
              }
           }
         }
      }
   }, 
    "sort" : [
    {
      "productCost.cost" : {
         "order" : "asc",
         "nested": {
            "path": "productCost"
         }
      }
    }
  ]
}

【讨论】:

    【解决方案3】:

    基本上有两种方法可以做到这一点。

    1. 通过使用布尔查询。在这种类型的查询中,您可以在查询中添加多个布尔运算符(must、must_not、should),然后在每个运算符中添加多种类型的子句,如下所示

    2. 使用查询字符串。 Elasticsearch 为您提供了编写查询的方法,其中包含多个查询,字符串中包含不同的子句

    布尔查询:

    POST _search
    {
      "query": {
        "bool" : {
          "must" : {
            "term" : { "user" : "kimchy" }
          },
          "filter": {
            "term" : { "tag" : "tech" }
          },
          "must_not" : {
            "range" : {
              "age" : { "gte" : 10, "lte" : 20 }
            }
          },
          "should" : [
            { "term" : { "tag" : "wow" } },
            { "term" : { "tag" : "elasticsearch" } }
          ],
          "minimum_should_match" : 1,
          "boost" : 1.0
        }
      }
    

    查询字符串:

    GET /_search
    {
        "query": {
            "query_string" : {
                "query" : "field1:value1 AND (field2:value2 or field2:value3) and  value4 and key5:(value6 or value7)",
                "default_field" : "content"
            }
        }
    }
    

    值 4 将在下面提到的 default_field 中找到

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-15
      • 1970-01-01
      • 2014-11-09
      • 1970-01-01
      • 1970-01-01
      • 2018-07-01
      相关资源
      最近更新 更多