3-Elasticsearch深入搜索-部分匹配

一起来玩Elasticsearch,加我微信:wx1250134974

Elasticsearch认证复习准备

https://www.elastic.co/guide/cn/elasticsearch/guide/current/getting-started.html

##部分匹配概念:

指定查找词的一部分并找出所有包含这部分片段的词。简单来说就是我输入Elas直接能给我匹配到Elasticsearch这个词。

 

 

##使用场景

*匹配邮编、产品序列号或其他 not_analyzed 未分析值,这些值可以是以某个特定前缀开始,也可以是与某种模式匹配的,甚至可以是与某个正则式相匹配的。

*输入即搜索(search-as-you-type) ——在用户键入搜索词过程的同时就呈现最可能的结果。

*匹配如德语或荷兰语这样有长组合词的语言,如: Weltgesundheitsorganisation 。(好多个词组成一个大词,这种我输入这个大词中的某几个字符就可以匹配到整个大词)

 

 

 

  1. 前缀查询

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 这样的正则式)。

 

  1. 查询时输入及搜索(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”

 

 

  1. 索引时输入及搜索

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,速度快好几倍。因为还是比较实用,另开一个文档。

 

 

  1. 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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值