ElasticSearch的nested类型(二)

311 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

近期在工作中需要使用es进行简单的全文检索,所以最近都在边学边做笔记,也会把自己遇到的bug以及如何解决的,一并记录在这里,供大家学习参考。

nested类型的精确查找

对nested类型所包含的字段的定义方式,如下图:

image.png

当我们需要对商品名称进行精确查找的时候,会因为type:text,不能查到期望的结果,只能进行模糊查询。

GET /test_order/_search
{
  "query": {
    "nested": {
      "path": "goodDoc",
      "query": {
        "match": {
          "goodDoc.goodName": {
            "query": "麦"
          }
        }
      },
      "inner_hits": {
        "highlight": {
          "fields": {
            "goodDoc.goodName": {}
          }
        }
      }
    }
    
  }
}

查询结果:

{
  "took" : 170,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.3112575,
    "hits" : [
      {
        "_index" : "test_order",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 1.3112575,
        "_source" : {
          "orderId" : 100002,
          "createdTime" : "2022-05-11",
          "userName" : "用户2",
          "goodDoc" : [
            {
              "goodName" : "麻花",
              "desc" : "黑芝麻味小麻花",
              "nums" : 3,
              "price" : 18
            },
            {
              "goodName" : "麦片",
              "desc" : "草莓多多奇亚籽水果麦片",
              "nums" : 5,
              "price" : 49
            }
          ]
        },
        "inner_hits" : {
          "goodDoc" : {
            "hits" : {
              "total" : {
                "value" : 1,
                "relation" : "eq"
              },
              "max_score" : 1.3112575,
              "hits" : [
                {
                  "_index" : "test_order",
                  "_type" : "_doc",
                  "_id" : "2",
                  "_nested" : {
                    "field" : "goodDoc",
                    "offset" : 1
                  },
                  "_score" : 1.3112575,
                  "_source" : {
                    "goodName" : "麦片",
                    "desc" : "草莓多多奇亚籽水果麦片",
                    "nums" : 5,
                    "price" : 49
                  },
                  "highlight" : {
                    "goodDoc.goodName" : [
                      "<em>麦</em>片"
                    ]
                  }
                }
              ]
            }
          }
        }
      }
    ]
  }
}

解决方法

在mapping里面设置fields,搜索的时候使用这个属性。

"goodName" : {
    "type" : "text",
    "fields" : {
      "keyword" : {
        "type" : "keyword",//增加这个字段后,goodName就可以进行精确查找
        "ignore_above" : 256
      }
    }
}

查询语句:

GET /test_order/_search
{
  "query": {
    "nested": {
      "path": "goodDoc",
      "query": {
        "match": {
          "goodDoc.goodName.keyword": {
            "query": "麦片"
          }
        }
      },
      "inner_hits": {
        "highlight": {
          "fields": {
            "goodDoc.goodName.keyword": {}
          }
        }
      }
    }
  }
}

查询结果:

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.3862942,
    "hits" : [
      {
        "_index" : "test_order",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 1.3862942,
        "_source" : {
          "orderId" : 100002,
          "createdTime" : "2022-05-11",
          "userName" : "用户2",
          "goodDoc" : [
            {
              "goodName" : "麻花",
              "desc" : "黑芝麻味小麻花",
              "nums" : 3,
              "price" : 18
            },
            {
              "goodName" : "麦片",
              "desc" : "草莓多多奇亚籽水果麦片",
              "nums" : 5,
              "price" : 49
            }
          ]
        },
        "inner_hits" : {
          "goodDoc" : {
            "hits" : {
              "total" : {
                "value" : 1,
                "relation" : "eq"
              },
              "max_score" : 1.3862942,
              "hits" : [
                {
                  "_index" : "test_order",
                  "_type" : "_doc",
                  "_id" : "2",
                  "_nested" : {
                    "field" : "goodDoc",
                    "offset" : 1
                  },
                  "_score" : 1.3862942,
                  "_source" : {
                    "goodName" : "麦片",
                    "desc" : "草莓多多奇亚籽水果麦片",
                    "nums" : 5,
                    "price" : 49
                  },
                  "highlight" : {
                    "goodDoc.goodName.keyword" : [
                      "<em>麦片</em>"
                    ]
                  }
                }
              ]
            }
          }
        }
      }
    ]
  }
}