一起来玩Elasticsearch,加我微信:wx1250134974
Elasticsearch认证复习准备
https://www.elastic.co/guide/cn/elasticsearch/guide/current/getting-started.html
##部分匹配概念:
指定查找词的一部分并找出所有包含这部分片段的词。简单来说就是我输入Elas直接能给我匹配到Elasticsearch这个词。
##使用场景
*匹配邮编、产品序列号或其他 not_analyzed 未分析值,这些值可以是以某个特定前缀开始,也可以是与某种模式匹配的,甚至可以是与某个正则式相匹配的。
*输入即搜索(search-as-you-type) ——在用户键入搜索词过程的同时就呈现最可能的结果。
*匹配如德语或荷兰语这样有长组合词的语言,如: Weltgesundheitsorganisation 。(好多个词组成一个大词,这种我输入这个大词中的某几个字符就可以匹配到整个大词)
- 前缀查询
GET /my_index/address/_search
{
"query": {
"prefix": {
"postcode": "W1"
}
}
}
注:prefix 查询不做相关度评分计算,它只是将所有匹配的文档返回,并为每条结果赋予评分值 1。前缀查询会遍历所有的倒排索引term项,可见如果数据量很大时,性能会很差,一般只在数据量少时使用
2、通配符查询
GET /my_index/address/_search
{
"query": {
"wildcard": {
"postcode": "W?F*HW"
}
}
}
3、正则表达式查询
GET /my_index/address/_search
{
"query": {
"regexp": {
"postcode": "W[0-9].+"
}
}
}
注:
wildcard 和 regexp 查询的工作方式与 prefix 查询完全一样,它们也需要扫描倒排索引中的词列表才能找到所有匹配的词,然后依次获取每个词相关的文档 ID ,与 prefix 查询的唯一不同是:它们能支持更为复杂的匹配模式。这也意味着需要同样注意前缀查询存在性能问题,对有很多唯一词的字段执行这些查询可能会消耗非常多的资源,所以要避免使用左通配这样的模式匹配(如: *foo 或 .*foo 这样的正则式)。
- 查询时输入及搜索(search as you type)
GET /megacorp/employee/_search
{
"query": {
"match_phrase_prefix": {
"about": "I love to go r"
}
}
}
GET /megacorp/employee/_search
{
"query": {
"match_phrase_prefix": {
"about": {
"query": "I love to go r",
"slop": 10, #词的顺序严格程度可以用这个调整
"max_expansions": 50 #最多匹配50个文档就结束了,提升性能
}
}
}
}
注:
这种查询的行为与 match_phrase 查询一致,不同的是它将查询字符串的最后一个词作为前缀使用,上方的例子就是说“I 跟着 love 跟着 to 跟着 go 跟着 r开头的term”
- 索引时输入及搜索
PUT /my_index #定义分析器
{
"settings": {
"number_of_shards": 1,
"analysis": {
"filter": {
"autocomplete_filter": { ##自定义的token过滤器
"type": "edge_ngram", ##边界n-grams
"min_gram": 1,
"max_gram": 20
}
},
"analyzer": {
"autocomplete": {
"type": "custom",
"tokenizer": "standard",
"filter": [
"lowercase",
"autocomplete_filter"
]
}
}
}
}
}
GET /my_index/_analyze?analyzer=autocomplete #测试下自定义的分析器
{
"text":"quick brown"
}
注:
通过分析的结果就可以知道这个为啥能用前缀匹配了。牺牲了写性能和磁盘空间,直接把所有的前缀都列出来了。和上方那种查询即搜索不同的是这个只在索引数据时慢一次。
PUT /my_index/my_type/_mapping #使用分析器
{
"my_type": {
"properties": {
"name": {
"type": "string",
"index_analyzer": "autocomplete",
"search_analyzer": "standard"
}
}
}
}
注:使用自定义的分析器,索引数据时使用autocomplete分析器,查询时使用standard分析器
GET /my_index/my_type/_search #测试下吧
{
"query": {
"match": {
"name": {
"query": "brown fo",
"analyzer": "standard"
}
}
}
}
注:
上方的term如何生成通过分析器的即可看出,用的时候,有时可能会需要指定analyzer代替默认的字段分析器,以提高准确性。
PUT /my_index #参考用的定义分析器的例子,可以更好的使用前缀查询
{
"settings": {
"number_of_shards": 1,
"analysis": {
"filter": {
"postcode_filter": { #定义token过滤器
"type": "edge_ngram",
"min_gram": 1,
"max_gram": 8
}
},
"analyzer": { #定义两个分析器
"postcode_index": {
"tokenizer": "keyword",
"filter": [
"postcode_filter"
]
},
"postcode_search": {
"tokenizer": "keyword"
}
}
}
}
}
注:
其实本节这些功能虽然可用,但是仍然还是比较慢的。自动补全(甚至搜索纠错)的功能还是用Elasticsearch Suggester,速度快好几倍。因为还是比较实用,另开一个文档。
- Ngrams 在复合词的应用
PUT /my_index #定义Ngrams分析器
{
"settings": {
"analysis": {
"filter": {
"trigrams_filter": {
"type": "ngram",
"min_gram": 3,
"max_gram": 3
}
},
"analyzer": {
"trigrams": {
"type": "custom",
"tokenizer": "standard",
"filter": [
"lowercase",
"trigrams_filter"
]
}
}
}
},
"mappings": {
"my_type": {
"properties": {
"text": {
"type": "string",
"analyzer": "trigrams"
}
}
}
}
}
GET /my_index/_analyze?analyzer=trigrams #测试下新的分析器
{
"text": "Weißkopfseeadler"
}
GET /my_index/my_type/_search #查询测试
{
"query": {
"match": {
"text": {
"query": "Gesundheit",
"minimum_should_match": "80%" #去掉长尾
}
}
}
}
一起来玩Elasticsearch,加我微信:wx1250134974