基于词项和基于全文的搜索
# 一、基于Term的查询
# 1、概念和特点
概念
Term是表达语意的最小单位,搜索和利用统计语言模型进行自然语言处理都需要处理Term。
特点
- 基于Term的查询:Term Query / Range Query / Exists Query / Prefix Query。
- 在ES中,Term查询,对输入不做分词,会将输入作为一个整体,在倒排索引中查找精确的词项,并对包含该词项的文档进行算分。
- 如果想要避免算分,并利用缓存,可以通过constant_score将查询转换成一个Filtering。
# 2、案例
数据准备
POST /products/_bulk
{ "index": { "_id": 1 }}
{ "productID" : "XHDK-A-1293-#fJ3","desc":"iPhone" }
{ "index": { "_id": 2 }}
{ "productID" : "KDKE-B-9947-#kL5","desc":"iPad" }
{ "index": { "_id": 3 }}
{ "productID" : "JODL-X-1937-#pV7","desc":"MBP" }
数据查询
POST /products/_search
{
"query": {
"term": {
"desc": {
"value": "iPhone"
}
}
}
}
这样一条查询语句查询结果是空,为什么呢?
这是因为Term查询,默认是会在倒排索引中查找精确的词项,但是ES默认的分词器会进行分词和小写处理,也就是iPhone
这个单词已经被分词和小写处理了,在倒排索引中它是为iphone
,所以无法匹配上。
POST /products/_search
{
"query": {
"term": {
"desc": {
"value": "iphone"
}
}
}
}
将单词改写成小写就可以精确匹配上了,如果不想更改单词的分词和大小写,可以使用如下方式进行查询:
POST /products/_search
{
"query": {
"term": {
"desc.keyword": {
"value": "iPhone"
}
}
}
}
如果我们想要避免算分,有效利用我们的缓冲:
POST /products/_search
{
"explain": true,
"query": {
"constant_score": {
"filter": {
"term": {
"productID.keyword": "XHDK-A-1293-#fJ3"
}
}
}
}
}
# 二、基于全文的查询
# 1、概念和特点
概念
基于全文本的查询主要有:
- Match Query
- Match Phrase Query
- Query String Query
特点
- 索引和搜索都会进行分词,查询字符串先传递到一个合适的分词器,然后生成一个供查询的列表。
- 查询时候,会对输入的查询进行分词,然后每个词项单独进行查询,然后将结果进行合并。比如查询 A B,会查询到包括A或者B的所有结果。
# 2、案例
数据准备
#设置 position_increment_gap
DELETE groups
PUT groups
{
"mappings": {
"properties": {
"names":{
"type": "text",
"position_increment_gap": 0
}
}
}
}
GET groups/_mapping
POST groups/_doc
{
"names": [ "John Water", "Water Smith"]
}
数据查询
POST groups/_search
{
"query": {
"match_phrase": {
"names": "Water"
}
}
}
POST groups/_search
{
"query": {
"match": {
"names": {
"query": "Water Smith",
"operator": "and"
}
}
}
}
# 参考
上次更新: 2024/06/29, 15:13:44