• ElasticSearch 分词基本概念 and es 中文分词 and es ik 中文分词 and es 全文搜索 and 单词搜索 and 多词搜索 and 组合搜索


    基本概念

    什么是分词?

    分词就是将一个文本转化成为一系列的单词的过程,也叫文本分析,在 ElasticSearch 中称之为 Analysis。
    默认是使用标准分词。
    举例:我是中国人 --> 我/是/中国人
    

    分词 api

    指定分词器进行分词
    

    分词测试

    POST:127.0.0.1:9200/_analyze 
    

    1、英文分词

    {
        "analyzer":"standard",
        "text":"hello world"
    }
    
    返回值:
    
    {
        "tokens": [
            {
                "token": "hello",
                "start_offset": 0,
                "end_offset": 5,
                "type": "<ALPHANUM>",
                "position": 0
            },
            {
                "token": "world",
                "start_offset": 6,
                "end_offset": 11,
                "type": "<ALPHANUM>",
                "position": 1
            }
        ]
    }
    

    2、中文分词

    {
        "analyzer": "standard",
        "text": "我是中国人"
    }
    
    返回值:分为5个词、并不合理。
    
    {
        "tokens": [
            {
                "token": "我",
                "start_offset": 0,
                "end_offset": 1,
                "type": "<IDEOGRAPHIC>",
                "position": 0
            },
            {
                "token": "是",
                "start_offset": 1,
                "end_offset": 2,
                "type": "<IDEOGRAPHIC>",
                "position": 1
            },
            {
                "token": "中",
                "start_offset": 2,
                "end_offset": 3,
                "type": "<IDEOGRAPHIC>",
                "position": 2
            },
            {
                "token": "国",
                "start_offset": 3,
                "end_offset": 4,
                "type": "<IDEOGRAPHIC>",
                "position": 3
            },
            {
                "token": "人",
                "start_offset": 4,
                "end_offset": 5,
                "type": "<IDEOGRAPHIC>",
                "position": 4
            }
        ]
    }
    

    3、指定索引,字段分词

    POST:127.0.0.1:9200/test/_analyze 
    
    {
        "analyzer": "standard",
        "field": "hobby",
        "text": "我是中国人"
    }
    

    中文分词

    1、释义

    中文分词的难点在于,在汉语中没有明显的词汇分界点,如在英语中,空格可以作为分隔符。如果分隔不正确就会造成歧义。
    
    如:
    我/爱/炒肉丝
    我/爱/炒/肉丝
    常用中文分词器, IK、jieba、 THULAC等,推荐使用IK分词器。
    
    分词地址:
    https://github.com/medcl/elasticsearch-analysis-ik
    

    2、安装 ik 分词器

    自动安装
    
     ./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.8.1/elasticsearch-analysis-ik-7.8.1.zip
    
    手动安装
    
    将下载到的 elasticsearch-analysis-ik-7.8.1. zip 解圧到 /elasticsearch/plugins/ik 目录下
    1 mkdir es/plugins/ik
    2 cp elasticsearch-analysis-ik-7.8.1.zip ./es/plugins/ik
    3 unzip elasticsearch-analysis-ik-7.8.1.zip
    4 ./bin/elasticsearch
    

    3、测试是否安装成功

    POST:127.0.0.1:9200/_analyze
     
    {
        "analyzer": "ik_max_word",
        "text": "我是中国人"
    }
    
    返回结果:
    {
        "tokens": [
            {
                "token": "我",
                "start_offset": 0,
                "end_offset": 1,
                "type": "CN_CHAR",
                "position": 0
            },
            {
                "token": "是",
                "start_offset": 1,
                "end_offset": 2,
                "type": "CN_CHAR",
                "position": 1
            },
            {
                "token": "中国人",
                "start_offset": 2,
                "end_offset": 5,
                "type": "CN_WORD",
                "position": 2
            },
            {
                "token": "中国",
                "start_offset": 2,
                "end_offset": 4,
                "type": "CN_WORD",
                "position": 3
            },
            {
                "token": "国人",
                "start_offset": 3,
                "end_offset": 5,
                "type": "CN_WORD",
                "position": 4
            }
        ]
    }
    

    全文搜索

    1、全文搜索两个最重要的方面:

    1、相关性( Relevance )它是评价查询与其结果间的相关程度,并根据这种相关程度对结果排名的一种能力,这种计算方式可以是TF/IDF方法、地理位置邻近、模糊相似,或其他的某些算法。
    2、分词( Analysis )它是将文本块转换为有区别的、规范化的token的一个过程,目的是为了创建倒排索引以及查询倒排索引。
    

    2、重置索引的分词

    PUT:127.0.0.1:9200/study
    
    {
        "settings": {
            "index": {
                "number_of_shards": "2",
                "number_of_replicas": "0"
            }
        },
        "mappings": {
            "properties": {
                "id": {
                    "type": "integer"
                },
                "name": {
                    "type": "text"
                },
                "age": {
                    "type": "integer"
                },
                "mail": {
                    "type": "keyword"
                },
                "desc": {
                    "type": "text",
                    "analyzer": "ik_max_word"
                }
            }
        }
    }
    

    3、数据添加

    POST:127.0.0.1:9200/study/_doc/_bulk
    
    { "create": { "_index": "study","_type": "_doc", "_id": "1001" }}
    { "id": 1001,"name": "1001","age": 11,"sex": "女", "desc": "指尖轻触玻窗,嗤嗤的响声,惊动了脆弱的心脏,一阵阵的酸楚,像浪潮般袭来,若果这样酸酸的痛可以代替撕心裂肺,那就让他长久点,这样时间会把我忘记,这样便可躲在这里,让那些软弱手舞足蹈,让那些脆弱和不堪拼命娱乐,让那颗紧绷的心,少少松弦。" }
    { "create": { "_index": "study","_type": "_doc", "_id": "1002" }}
    { "id": 1002,"name": "1002","age": 12,"sex": "女", "desc": "曾过往,伊颜纯美无暇,如玉般璀璨,许多人像发现了财富,紧抱于怀,怜香般害怕失去。那时,遇见你的是洗礼过后的悔过者,只懂怜香,而不懂惜玉,再璀璨也掩盖不了他身上久积的灰尘,铸造不了你,也成就不了他,于是乎,迷糊坚固了戏剧化的情谊,疼只是简单的疼。" }
    { "create": { "_index": "study","_type": "_doc", "_id": "1003" }}
    { "id": 1003,"name": "1003","age": 13,"sex": "女", "desc": "岁月还远,徐徐的风吹着,却也有了几分萧瑟,春天,不仅有满天飘飞的花儿,还有到处弥散着花的幽香。随着秋韵渐渐浓郁起来,院子里的花便盛开了,整个院子里香气四溢,溢漫着甜丝丝的味儿。金灿的花儿一串串、一撮撮,重重叠叠簇涌着点缀在茂密的绿叶之间,温温暖暖象极了一个个孩子的笑脸,仿佛是给这温暖的春天注入了一道亮丽的风景。" }
    { "create": { "_index": "study","_type": "_doc", "_id": "1004" }}
    { "id": 1004,"name": "1004","age": 14,"sex": "女", "desc": "樱花有单樱和双樱,她们绽放时满树灿烂,清香扑鼻,单樱白的如雪如云,双樱色彩如火似霞。但是无论是单樱还是双樱,她们盛开的时间都不长,二十多天的光景,开的绚丽多彩、满树烂漫,落得星星瓣瓣,匆匆忙忙。" }
    { "create": { "_index": "study","_type": "_doc", "_id": "1005" }}
    { "id": 1005,"name": "1005","age": 15,"sex": "女", "desc": "真正的相爱,是人在千里,却梦魂相依;真正的相爱,是岁月流转,却不离不弃;真正的相爱,是彼此付出,却无怨无悔。" }
    { "create": { "_index": "study","_type": "_doc", "_id": "1006" }}
    

    单词搜索

    POST: 127.0.0.1:9200/study/_doc/_search
    
    {
        "query":{
            "match": {
                "desc": "时光"
            }
        }
    }
    
    过程说明
    
    1.检查字段类型
        描述字段 desc 是一个text类型(指定了IK分词器), 这意味着查询字符串本身也应该被分词。
    2.分析查询字符串.
        将查询的字符串“音乐传入IK分词器中,输出的结果是单个项音乐。因为只有一个单词项,所以match查询执行的是单个底层term查询。
    3.查找匹配文档。
        用term查询在倒排索引中查找“音乐”然后获取-组包含该项的文档。
    4.为每个文档评分。
        用term查询计算每个文档相关度评分. score ,这是种将词频( term frequency ,即词“时光"在相关文档的 desc 字段中出现的频率)和反向文档频率t inverse document frequency ,即词“时光"在所有文档的 desc 字段中出现的频率) , 以及字段的长度(即字段越短相关度越高)相结合的计算方式。
    

    多词搜索

    POST: 127.0.0.1:9200/study/_doc/_search
        
    {
        "query":{
            "match": {
                "desc": "时光 岁月"
            }
        }
    }
    

    1、operator

    可以发现结果中,包含了 "时光"、 "岁月"的数据都已经被搜索到了。
    可是,搜索的结果并不是我们的预期,因为我们想要的是即包含"时光",又包含"岁月"的用户,显然结果返回的是 或者 的关系。
    在 ElasticSearch 中可以通过 operator 指定分词之间的逻辑关系, 默认是 or, 具体如下:
    
    POST: 127.0.0.1:9200/study/_doc/_search
            
    {
        "query": {
            "match": {
                "desc": {
                    "query": "时光 岁月",
                    "operator": "and"
                }
            }
        }
    }
    

    2、最小匹配度 minimum_should_match

    前面我们测试了"OR"和“AND"搜索,这是两个极端,其实在实际场景中, 并不会选取这2个极端,更有可能是选取这种,或者说,只需要符合一定的相似度就可以查询到数据;
    match 查询还支持 minimum_should_match 最小匹配参数,这个可以指定必须匹配的词项数用来表示一个文档是否相关。
    我们可以将其设置为一个具体的数字,通常的做法是将其设置为一个百分数:如: 70% ;
    
    POST: 127.0.0.1:9200/study/_doc/_search
    
    {
        "query": {
            "match": {
                "desc": {
                    "query": "时光 岁月",
                    "minimum_should_match": "50%"
                }
            }
        }
    }
    
    相似度应该多少合适呢?需要在实际的需求中进行反复测试,才可以得到合理的值。
    

    组合搜索

    POST: 127.0.0.1:9200/study/_doc/_search
    
    {
        "query": {
            "bool": {
                "must": {
                    "match": {
                        "desc": "时光"
                    }
                },
                "must_not": {
                    "match": {
                        "desc": "日子"
                    }
                },
                "should": [
                    {
                        "match": {
                            "desc": "岁月"
                        }
                    }
                ]
            }
        }
    }
    
    上面搜索的意思是:
    搜索结果中必须包含时光,不能包含日子,如果包含了岁月,那么他的相似度会更高。
    
    评分的计算规则:
    bool查询会为每一个文档计算相关度评分 _score, 在将所有匹配的 must 和 should 语句的分数 _score 求和。
    最后除以 must 和 should 语句的总数。
    must_not 语句不会影响评分;他的作用只是将不相关的文档排除。
    
    默认情况下,should 中的内容不是必须匹配的,如果查询语句中没有 must,那么就会至少匹配其中一个。
    当然也可以通过 minimum_should_match 参数进行控制,该值可以数字。也可以是百分比。
    

    权重 boost

    有些时候,我们可能需要对某些词增加权重来影响该条数据的评分。

    搜索关键字为"时光 岁月", 如果包含了"日子" 权重为10,如果包含了"还远"权重为2。
    
    POST: 127.0.0.1:9200/study/_doc/_search
    
    {
        "query": {
            "bool": {
                "must": {
                    "match": {
                        "desc": {
                            "query": "时光 岁月",
                            "operator": "and"
                        }
                    }
                },
                "should": [
                    {
                        "match": {
                            "desc": {
                                "query": "日子",
                                "boost": 10
                            }
                        }
                    },
                    {
                        "match": {
                            "desc": {
                                "query": "还远",
                                "boost": 2
                            }
                        }
                    }
                ]
            }
        }
    }
  • 相关阅读:
    POJ 3254 Corn Fields
    【Android】手机号码获取问题
    iOS自动自动隐藏软键盘
    cocos2d-x教程1 hello world
    ORA-02396: exceeded maximum idle time, please connect again的原因
    [置顶] WebService调用工具(AXIS2)
    经典union的使用
    Android Developers:按需求加载视图
    android手机关于google play商店闪退的解决办法
    [置顶] 两主机搭建MySQL主从复制后,show slave status显示:Last_IO_Error: error connecting to master ……
  • 原文地址:https://www.cnblogs.com/laowenBlog/p/13450053.html
Copyright © 2020-2023  润新知