当前位置: 首页 > 工具软件 > quick-query > 使用案例 >

《Elasticsearch:权威指南》Query DSL -- Term-level queries --Term Query

蓬森
2023-12-01

Term Query(精确词查询)

精确词查询查找倒排索引中指定的精确词的文档。 例如:

精确词查找特指keyword类型数据,未经分词处理。

POST twitter/_search
{
  "query": {
    "term" : { "user" : "Kimchy" }   //查询user字段并且值为Kimchy的文档
  }
}

注意:这里的Kimchy中的K是大写的,在《Elasticsearch:权威指南》Document APIs – Index API 中的例子是小写的k,小心被坑死了

boost参数

为了讲解下面的boost参数,我们先把上面的例子改造一下,二者等价:

{
	"query": {
		"term": {
			"user": {     //user字段
				"value": "kimchy",      //value属性指向值
				"boost": 1.0   //权重系数
			}
		}
	}
}

一个字段,可以扩展为带有value和boost的结构,boost默认值为1.0

可以指定boost参数,以使该精确词查询比其他查询具有更高的相关性得分,例如:

GET _search
{
  "query": {
    "bool": {
      "should": [
        {
          "term": {
            "status": {     //指status字段
              "value": "urgent",   //查询条件的值
              "boost": 2.0    //权重设置2.0
            }
          }
        },
        {
          "term": {
            "status": "normal" 
          }
        }
      ]
    }
  }
}
  1. 上面例子中urgent的boost值设置为2,说明重要性是2倍于normal
  2. boost默认值为1.0

为什么term query会匹配不到数据

字符串字段的类型可以是text(作为全文,如电子邮件的正文)或 keyword (作为精确值,如电子邮件地址或邮政编码)。精确值(如数字,日期和关键字)具有在字段中指定的确切值,该字段已添加到倒排索引中,以使其可搜索。

但是,text 字段是被分词处理的。这意味着它们的值首先会通过分析器生成一个词语列表,然后将其添加到倒排索引中。

分析文本的方法有很多:默认的标准分析器会删除大多数标点符号,将文本分解为单个单词,然后将其小写。例如,标准分析仪会将字符串“ Quick Brown Fox!”变成词语 [quick, brown, fox]

通过这种分析过程,可以在一大段全文本中搜索单个单词。

term query 查询 会在字段的倒排索引中查找确切的字词-对该字段的分析器一无所知。这对于在关键字字段,数字字段或日期字段中查找值很有用。查询全文字段时,请使用match query 匹配查询,该查询可了解如何分析该字段。

为了演示,请尝试以下示例。首先,创建一个索引,指定字段映射,并为文档建立索引:

PUT my_index
{
  "mappings": {
    "_doc": {
      "properties": {
        "full_text": {                 
          "type":  "text"       //text类型,会分词
        },
        "exact_value": {
          "type":  "keyword"  //keyword类型,不会分词
        }
      }
    }
  }
}

PUT my_index/_doc/1
{
  "full_text":   "Quick Foxes!", 
  "exact_value": "Quick Foxes!"  
}
  • full_text字段是 text类型,会分词

  • exact_value 字段是 keyword类型,不会分词

  • full_text 字段倒排索引 包含词语: [quick, foxes],2个单词

  • exact_value 字段倒排索引包含词语: [Quick Foxes!],一个单词

那么,下面来比较下term query 和 match query的不同之处

GET my_index/_search
{
  "query": {
    "term": {      //精确匹配
      //能匹配到数据,因为未分词,内部存储‘Quick Foxes!’,一个完整字符串,与查询条件完全匹配
      //等价于 表达式 "Quick Foxes!"== "Quick Foxes!",结果“是”
      "exact_value": "Quick Foxes!"   
    }
  }
}

GET my_index/_search
{
  "query": {
    "term": {      //精确匹配
     //匹配失败,因为分词,内部存储为: [quick, foxes],2个单词
     // 等价于 表达式"Quick Foxes!"==quick  or "Quick Foxes!"==foxes ,结果“否”
      "full_text": "Quick Foxes!"   
    }
  }
}

GET my_index/_search
{
  "query": {     
    "term": {     //精确匹配
      //能匹配,因为分词,内部存储为: [quick, foxes],2个单词
      // 等价于 表达式 "foxes"in  [quick, foxes],结果“是”
      "full_text": "foxes" 
    }
  }
}

GET my_index/_search
{
  "query": {
    "match": {     //模糊匹配
    //能匹配,条件也会分词,内部存储也是分词
    //等价于 表达式 [quick, foxes] in [quick, foxes]  ,结果“是”
      "full_text": "Quick Foxes!" 
    }
  }
}

经过上面的例子,大致可以分清term query和math query了,首先term query查询条件不会分词,match query查询条件会分词,然后根据字段存储的格式,text会分词,内部拆分成多个词语,keyword不会分词,内部就保存一个完整的词。然后进行比较。

由于head插件不方便在发送get请求时,不会携带body参数,我们在linux上使用curl命令测试:

curl  -XGET "10.40.164.63:9200/my_index/_search"  --header "Content-Type:application/json" -d ' 
{
  "query": {
    "term": {
      "exact_value": "Quick Foxes!" 
    }
  }
}'
 类似资料: