【问题标题】:Why is there a difference in the search results when querying elasticsearch using a term query?为什么使用term查询查询elasticsearch时搜索结果会有差异?
【发布时间】:2021-07-13 07:04:30
【问题描述】:

我最近开始学习弹性搜索,并且我的查询的搜索结果有所不同。下面提供了名为“products”的索引的映射(我正在粘贴来自我的 Kibana 控制台工具的响应):

    {
    "products" : {
"mappings" : {
  "properties" : {
    "in_stock" : {
      "type" : "long"
    },
    "name" : {
      "type" : "text",
      "fields" : {
        "keyword" : {
          "type" : "keyword",
          "ignore_above" : 256
        }
      }
    },
    "price" : {
      "type" : "long"
    },
    "tags" : {
      "type" : "text",
      "fields" : {
        "keyword" : {
          "type" : "keyword",
          "ignore_above" : 256
        }
      }
    }
  }
}
}
}

索引中的数据如下(我正在粘贴来自我的 Kibana 控制台工具的响应):

{
   "took" : 0,
  "timed_out" : false,
  "_shards" : {
  "total" : 1,
  "successful" : 1,
  "skipped" : 0,
  "failed" : 0
  },
  "hits" : {
"total" : {
  "value" : 16,
  "relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
  {
    "_index" : "products",
    "_type" : "_doc",
    "_id" : "202",
    "_score" : 1.0,
    "_source" : {
      "name" : "Vegetable Chopper",
      "price" : 10,
      "in_stock" : 250,
      "tags" : [
        "kitchen appliances",
        "vegetable slicer",
        "chopper"
      ]
    }
  },
  {
    "_index" : "products",
    "_type" : "_doc",
    "_id" : "203",
    "_score" : 1.0,
    "_source" : {
      "name" : "Dish Washer",
      "price" : 90,
      "in_stock" : 60,
      "tags" : [
        "kitchen appliances",
        "electrical",
        "electric washer"
      ]
    }
  },
  {
    "_index" : "products",
    "_type" : "_doc",
    "_id" : "205",
    "_score" : 1.0,
    "_source" : {
      "name" : "Microwave Oven",
      "price" : 100,
      "in_stock" : 50,
      "tags" : [
        "kitchen appliances",
        "electricals",
        "oven",
        "oven toaster",
        "microwave"
      ]
    }
  },
  {
    "_index" : "products",
    "_type" : "_doc",
    "_id" : "206",
    "_score" : 1.0,
    "_source" : {
      "name" : "Mixer Grinder",
      "price" : 55,
      "in_stock" : 130,
      "tags" : [
        "kitchen appliances",
        "electricals",
        "mixer",
        "grinder",
        "juicer",
        "food processor"
      ]
    }
  },
  {
    "_index" : "products",
    "_type" : "_doc",
    "_id" : "207",
    "_score" : 1.0,
    "_source" : {
      "name" : "Fruit Juicer",
      "price" : 40,
      "in_stock" : 100,
      "tags" : [
        "kitchen appliances",
        "electicals",
        "juicer",
        "mixer",
        "electric juicer",
        "juice maker"
      ]
    }
  },
  {
    "_index" : "products",
    "_type" : "_doc",
    "_id" : "208",
    "_score" : 1.0,
    "_source" : {
      "name" : "Knife Set",
      "price" : 15,
      "in_stock" : 250,
      "tags" : [
        "kitchen knife",
        "steel knives",
        "cutlery"
      ]
    }
  },
  {
    "_index" : "products",
    "_type" : "_doc",
    "_id" : "209",
    "_score" : 1.0,
    "_source" : {
      "name" : "Rice Maker",
      "price" : 85,
      "in_stock" : 60,
      "tags" : [
        "kitchen appliances",
        "electricals",
        "electric rice cooker",
        "electric pressure cooker"
      ]
    }
  },
  {
    "_index" : "products",
    "_type" : "_doc",
    "_id" : "210",
    "_score" : 1.0,
    "_source" : {
      "name" : "Induction Cooktop",
      "price" : 30,
      "in_stock" : 150,
      "tags" : [
        "kitchen appliances",
        "electricals",
        "hot plate heater",
        "electric hot place",
        "induction cooker",
        "induction stove"
      ]
    }
  },
  {
    "_index" : "products",
    "_type" : "_doc",
    "_id" : "211",
    "_score" : 1.0,
    "_source" : {
      "name" : "Coffee Maker",
      "price" : 50,
      "in_stock" : 100,
      "tags" : [
        "kitchen appliances",
        "electricals"
      ]
    }
  },
  {
    "_index" : "products",
    "_type" : "_doc",
    "_id" : "212",
    "_score" : 1.0,
    "_source" : {
      "name" : "Wine Glasses Set",
      "price" : 50,
      "in_stock" : 70,
      "tags" : [
        "kitchen and dining",
        "glassware",
        "stemware"
      ]
    }
  },
  {
    "_index" : "products",
    "_type" : "_doc",
    "_id" : "213",
    "_score" : 1.0,
    "_source" : {
      "name" : "Dinner Set",
      "price" : 100,
      "in_stock" : 40,
      "tags" : [
        "kitchen and dining",
        "crockery",
        "full dinner set"
      ]
    }
  },
  {
    "_index" : "products",
    "_type" : "_doc",
    "_id" : "214",
    "_score" : 1.0,
    "_source" : {
      "name" : "Whiskey Glasses Set",
      "price" : 60,
      "in_stock" : 50,
      "tags" : [
        "kitchen and dining",
        "glassware",
        "whiskey glasses",
        "old fashioned glass",
        "rocks glass",
        "short tumbler"
      ]
    }
  },
  {
    "_index" : "products",
    "_type" : "_doc",
    "_id" : "215",
    "_score" : 1.0,
    "_source" : {
      "name" : "Mug And Saucer Set",
      "price" : 35,
      "in_stock" : 60,
      "tags" : [
        "kitchen and dining",
        "mug set",
        "mugs and saucer",
        "crockery set"
      ]
    }
  },
  {
    "_index" : "products",
    "_type" : "_doc",
    "_id" : "201",
    "_score" : 1.0,
    "_source" : {
      "name" : "Milk Frother",
      "price" : 25,
      "in_stock" : 15,
      "tags" : [
        "kitchen appliances",
        "electricals",
        "milk"
      ]
    }
  },
  {
    "_index" : "products",
    "_type" : "_doc",
    "_id" : "200",
    "_score" : 1.0,
    "_source" : {
      "name" : "Espresso Maker",
      "price" : 180,
      "in_stock" : 5,
      "tags" : [
        "kitchen appliances",
        "electrical",
        "coffee maker"
      ]
    }
  },
  {
    "_index" : "products",
    "_type" : "_doc",
    "_id" : "204",
    "_score" : 1.0,
    "_source" : {
      "name" : "Pressure Fryer",
      "price" : 120,
      "in_stock" : 50,
      "tags" : [
        "air fryer",
        "kitchen appliances",
        "electric fryer",
        "fryer",
        "health fryer"
      ]
    }
  }
]
  }
}

使用下面的查询查询数据时,我只匹配了六条记录: 查询 - 1

GET /products/_search
{
  "query": {"terms" : {"tags": ["kitchen appliances","electricals"]}}
}

匹配的文档id是(201,205,206,209,210,211)

当我执行以下查询时,我匹配了 11 条记录: 查询-2

GET /products/_search
{
  "query": {"terms" : {"tags.keyword": ["kitchen appliances","electricals"]}}
}

与第二个查询匹配的文档 ID 为:(200,201,202,203,204,205,206,207,209,210,211)

有人能解释一下这两个查询有什么区别吗?为什么 Query-1 是 Query-2 的一个子集,即使两个查询都是在同一个字段上执行的?

【问题讨论】:

  • 查询不在同一个字段上执行。 tagstags.keyword 是两个不同的字段,具有两种不同的类型。

标签: elasticsearch elastic-stack term-query


【解决方案1】:

如果您有text 类型字段,最好使用match 查询。

term query 不对术语进行任何分析。它返回包含精确术语匹配文档的文档。

terms query 使用精确的术语。它返回那些具有 1 个或多个确切术语的文档。


问题 1:

{
  "query": {
    "terms": {
      "tags": [
        "kitchen appliances",
        "electricals"
      ]
    }
  }
}

搜索结果是

"hits": [
      {
        "_index": "67155973",
        "_type": "_doc",
        "_id": "3",
        "_score": 1.0,
        "_source": {
          "name": "Microwave Oven",
          "price": 100,
          "in_stock": 50,
          "tags": [
            "kitchen appliances",
            "electricals",
            "oven",
            "oven toaster",
            "microwave"
          ]
        }
      },
      {
        "_index": "67155973",
        "_type": "_doc",
        "_id": "4",
        "_score": 1.0,
        "_source": {
          "name": "Mixer Grinder",
          "price": 55,
          "in_stock": 130,
          "tags": [
            "kitchen appliances",
            "electricals",
            "mixer",
            "grinder",
            "juicer",
            "food processor"
          ]
        }
      },
      {
        "_index": "67155973",
        "_type": "_doc",
        "_id": "7",
        "_score": 1.0,
        "_source": {
          "name": "Rice Maker",
          "price": 85,
          "in_stock": 60,
          "tags": [
            "kitchen appliances",
            "electricals",
            "electric rice cooker",
            "electric pressure cooker"
          ]
        }
      },
      {
        "_index": "67155973",
        "_type": "_doc",
        "_id": "8",
        "_score": 1.0,
        "_source": {
          "name": "Induction Cooktop",
          "price": 30,
          "in_stock": 150,
          "tags": [
            "kitchen appliances",
            "electricals",
            "hot plate heater",
            "electric hot place",
            "induction cooker",
            "induction stove"
          ]
        }
      },
      {
        "_index": "67155973",
        "_type": "_doc",
        "_id": "9",
        "_score": 1.0,
        "_source": {
          "name": "Coffee Maker",
          "price": 50,
          "in_stock": 100,
          "tags": [
            "kitchen appliances",
            "electricals"
          ]
        }
      },
      {
        "_index": "67155973",
        "_type": "_doc",
        "_id": "14",
        "_score": 1.0,
        "_source": {
          "name": "Milk Frother",
          "price": 25,
          "in_stock": 15,
          "tags": [
            "kitchen appliances",
            "electricals",
            "milk"
          ]
        }
      }
    ]

documentation中所述

词条查询不分析搜索词条。仅术语查询 搜索您提供的确切字词。这意味着术语查询可能 搜索文本字段时返回较差的结果或没有结果。


问题 2:

{
  "query": {
    "terms": {
      "tags.keyword": [
        "kitchen appliances",
        "electricals"
      ]
    }
  }
}

在上面的查询中,您使用的是tags.keyword 字段,它使用关键字分析器而不是标准分析器。在这里,查询搜索确切的术语,即"kitchen appliances" OR "electricals",因此返回 11 个文档。

【讨论】:

  • 是的,先生,我确实完成了答案,它主要解释了关键字分析器和标准分析器的工作,但我的疑问是在两个查询中我们都使用了“术语”查询和我了解术语查询未分析。期待这个问题的答案。
  • @SarvagyaDubey 术语查询不分析文本。建议使用带有keyword 类型字段的term/terms 查询以获得准确的结果。在elasticsearch官方文档中也提到,term query在搜索文本字段时可能会返回很差或没有结果。 --> elastic.co/guide/en/elasticsearch/reference/7.12/…
  • 再次感谢先生。
猜你喜欢
  • 2011-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-09
  • 1970-01-01
  • 2011-03-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多