基于词项和基于全文的搜索
Term查询
定义
示例
创建索引并插入数据
DELETE products
PUT products
{
"settings": {
"number_of_shards": 1
}
}
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" }
使用term查询
POST /products/_search
{
"query": {
"term": {
"desc": {
"value": "iPhone"
}
}
}
}
搜索结果为空
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 0,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
}
}
原因:因为term查询不会对查询的内容进行分词处理,而索引时的standard分词器(默认分析器,按词切分,小写处理)会将iPhone,转换为iphone,所以无法匹配,查询为空。
eg.
GET /_analyze
{
"analyzer": "standard",
"text": ["iPhone"]
}
返回分词结果
{
"tokens" : [
{
"token" : "iphone",
"start_offset" : 0,
"end_offset" : 6,
"type" : "<ALPHANUM>",
"position" : 0
}
]
}
因此,想要匹配到查询,可以使用多字段搜索
多字段搜索
ES中,自动生成的动态Mapping中的每一个text中会包含一个keyword,所有我们也可以使用keyword来进行term搜索
eg.
POST /products/_search
{
"query": {
"term": {
"productID.keyword": {
"value": "XHDK-A-1293-#fJ3"
}
}
}
}
返回结果
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 0.9808292,
"hits" : [
{
"_index" : "products",
"_type" : "_doc",
"_id" : "1",
"_score" : 0.9808292,
"_source" : {
"productID" : "XHDK-A-1293-#fJ3",
"desc" : "iPhone"
}
}
]
}
}
复合查询,Filter过滤
在使用query时,每次查询都会进行打分操作,返回所有相关的结果,而有时我们的term查询只希望返回匹配到的结果而不进行打分操作,这是我们可以使用filter,配合constant_socre忽略打分操作,提高查询的性能,并且使用filter后会自动缓存,提高查询的效率
POST /products/_search
{
"explain": true,
"query": {
"constant_score": {
"filter": {
"term": {
"desc.keyword": "iPhone"
}
}
}
}
}
返回结果
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_shard" : "[products][0]",
"_node" : "RnkqhfTUSWq-fbgVmbhkfA",
"_index" : "products",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"productID" : "XHDK-A-1293-#fJ3",
"desc" : "iPhone"
},
"_explanation" : {
"value" : 1.0,
"description" : "ConstantScore(desc.keyword:iPhone)",
"details" : [ ]
}
}
]
}
}
可以看到得分是1.0
基于全文的查询
示例
match默认的operator是AND
minimum_should_match:最少匹配的词的数量,也可以填百分数,表示最少匹配多少比例的单词
match_phrase 短语匹配,要求单词的位置、顺序必须一致,slop可以灵活的控制位置和顺序。参见:
https://elasticsearch.cn/book/elasticsearch_definitive_guide_2.x/slop.html
match的查询过程分析
- 先对查询内容进行分词处理
- 对每一个分出来的单词进行查询,并且打分
- 汇总所有单词的得分
- 按照单词得分进行排序,返回结果
课程demo
DELETE products
PUT products
{
"settings": {
"number_of_shards": 1
}
}
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" }
GET /products
POST /products/_search
{
"query": {
"term": {
"desc": {
//"value": "iPhone"
"value":"iphone"
}
}
}
}
POST /products/_search
{
"query": {
"term": {
"desc.keyword": {
//"value": "iPhone"
//"value":"iphone"
}
}
}
}
POST /products/_search
{
"query": {
"term": {
"productID": {
"value": "XHDK-A-1293-#fJ3"
}
}
}
}
POST /products/_search
{
//"explain": true,
"query": {
"term": {
"productID.keyword": {
"value": "XHDK-A-1293-#fJ3"
}
}
}
}
POST /products/_search
{
"explain": true,
"query": {
"constant_score": {
"filter": {
"term": {
"productID.keyword": "XHDK-A-1293-#fJ3"
}
}
}
}
}
#设置 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": {
"query": "Water Water",
"slop": 100
}
}
}
}
POST groups/_search
{
"query": {
"match_phrase": {
"names": "Water Smith"
}
}
}
相关阅读
- https://www.elastic.co/guide/en/elasticsearch/reference/7.1/term-level-queries.html
- https://www.elastic.co/guide/en/elasticsearch/reference/7.1/full-text-queries.html
Filter和Query的区别
参见:http://xiaorui.cc/2015/11/09/elasticsearch%E7%9A%84%E6%9F%A5%E8%AF%A2%E5%99%A8query%E4%B8%8E%E8%BF%87%E6%BB%A4%E5%99%A8filter%E7%9A%84%E5%8C%BA%E5%88%AB/