1 数据准备
1.1 创建索引和新增数据
先新增一条数据,新增数据时会自动创建索引 test_standard_analyzer。
PUT /test_standard_analyzer/_doc/1
{"remark": "This is a test doc"
}
然后查询一下。
GET test_standard_analyzer/_search
{"query": {"match_all": {}}
}
查询结果如下所示。
{"took" : 2,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 1,"relation" : "eq"},"max_score" : 1.0,"hits" : [{"_index" : "test_standard_analyzer","_type" : "_doc","_id" : "1","_score" : 1.0,"_source" : {"remark" : "This is a test doc"}}]}
}
1.2 测试分词
没指定es分词器时,es会使用默认分词器-standard。测试下分词效果。
POST test_standard_analyzer/_analyze
{"field": "remark","text": "This is a test doc"
}# 或POST test_standard_analyzer/_analyze
{"analyzer": "standard","text": "This is a test doc"
}
分词结果如下所示。
{"tokens" : [{"token" : "this","start_offset" : 0,"end_offset" : 4,"type" : "<ALPHANUM>","position" : 0},{"token" : "is","start_offset" : 5,"end_offset" : 7,"type" : "<ALPHANUM>","position" : 1},{"token" : "a","start_offset" : 8,"end_offset" : 9,"type" : "<ALPHANUM>","position" : 2},{"token" : "test","start_offset" : 10,"end_offset" : 14,"type" : "<ALPHANUM>","position" : 3},{"token" : "doc","start_offset" : 15,"end_offset" : 18,"type" : "<ALPHANUM>","position" : 4}]
}
2 ES查询
2.1 match
match查询会将查询条件进行分词。命中数据的条件:匹配到查询条件的其中一个分词即可。
以下查询将命中数据,查询条件被分词为“b”和“doc”。
GET test_standard_analyzer/_search
{"query": {"match": {"remark":"b doc"}}
}
2.2 match_phrase
match查询也会将查询条件进行分词。
命中数据的条件:(1)查询条件的所有分词都需要匹配到,(2)相对顺序还要一致,(3)默认(slop=0或者未设置该值)查询条件的分词在es数据中是连续的。
2.2.1 查询条件的分词在es数据中需要是连续的
(1)命中数据
GET test_standard_analyzer/_search
{"query": {"match_phrase": {"remark":"a test doc"}}
}
(2)未命中数据
以下查询未命中数据,因为查询条件的分词在es数据中不连续,中间还间隔一个“test”。
GET test_standard_analyzer/_search
{"query": {"match_phrase": {"remark":"a doc"}}
}
2.2.2 查询条件的分词在es数据中不需要是连续的
slop 参数用于指定中间可省略几个词语。slop > 0时,查询条件的分词在es数据中可以不连续。
因此以下查询将命中数据。
GET test_standard_analyzer/_search
{"query": {"match_phrase": {"remark":{"query": "a doc","slop": 1}}}
}
3 参考文献
(1)【ES知识】ES基础查询语法一览