• 全文搜索


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

        PUT /fan

    {
        "settings": {
            "index": {
                "number_of_shards": "1",
                "number_of_replicas": "0"
            }
        },
        "mappings": {
            "person": {
                "properties": {
                    "name": {
                        "type": "text"
                    },
                    "age": {
                        "type": "integer"
                    },
                    "mail": {
                        "type": "keyword"
                    },
                    "hobby": {
                        "type": "text",
                        "analyzer": "ik_max_word"
                    }
                }
            }
        }
    }
    View Code

        批量插入数据:POST /fan/_bulk

    {"index":{"_index":"fan","_type":"person"}}
    {"name":"张三","age": 20,"mail": "111@qq.com","hobby":"羽毛球、乒乓球、足球"}
    {"index":{"_index":"fan","_type":"person"}}
    {"name":"李四","age": 21,"mail": "222@qq.com","hobby":"羽毛球、乒乓球、足球、篮球"}
    {"index":{"_index":"fan","_type":"person"}}
    {"name":"王五","age": 22,"mail": "333@qq.com","hobby":"羽毛球、篮球、游泳、听音乐"}
    {"index":{"_index":"fan","_type":"person"}}
    {"name":"赵六","age": 23,"mail": "444@qq.com","hobby":"跑步、游泳、篮球"}
    {"index":{"_index":"fan","_type":"person"}}
    {"name":"孙七","age": 24,"mail": "555@qq.com","hobby":"听音乐、看电影、羽毛球"}
    View Code

      2.单词搜索

        POST /fan/person/_search

    {
        "query": {
            "match": {
                "hobby": "音乐"
            }
        },
        "highlight": {
            "fields": {
                "hobby": {}
            }
        }
    }

        过程说明:
          1. 检查字段类型
            hobby 字段是一个 text 类型( 指定了IK分词器),这意味着查询字符串本身也应该被分词。
          2. 分析查询字符串 。
            将查询的字符串 “音乐” 传入IK分词器中,输出的结果是单个项 音乐。因为只有一个单词项,所以 match 查询执行的是单个底层 term 查询。
          3. 查找匹配文档 。
            用 term 查询在倒排索引中查找 “音乐” 然后获取一组包含该项的文档

          4. 为每个文档评分 。
            用 term 查询计算每个文档相关度评分 _score ,这是将 词频(term frequency,即词 “音乐” 在相关文档的 hobby 字段中出现的频率)和 反向文档频率(inverse document frequency,即词 “音乐” 在所有文档的 hobby 字段中出现的频率),以及字段的长度(即字段越短相关度越高)相结合的计算方式。

      3.多词搜索

        POST /fan/person/_search

    {
        "query": {
            "match": {
                "hobby": "音乐 篮球"
            }
        },
        "highlight": {
            "fields": {
                "hobby": {}
            }
        }
    }

        可以看到,包含了“音乐”、“篮球”的数据都已经被搜索到了。

        可是,搜索的结果并不符合我们的预期,因为我们想搜索的是既包含“音乐”又包含“篮球”的用户,显然结果返回的“或”的关系。
        在Elasticsearch中,可以指定词之间的逻辑关系,如下:

    {
        "query": {
            "match": {
                "hobby": {
                    "query": "音乐 篮球",
                    "operator": "and"
                }
            }
        },
        "highlight": {
            "fields": {
                "hobby": {}
            }
        }
    }

        前面我们测试了“OR” 和 “AND”搜索,这是两个极端,其实在实际场景中,并不会选取这2个极端,更有可能是选取只需要符合一定的相似度就可以查询到数据,在Elasticsearch中也支持这样的查询,通过minimum_should_match来指定匹配度,如:70%,相似度应该多少合适,需要在实际的需求中进行反复测试,才可得到合理的值。

    {
        "query": {
            "match": {
                "hobby": {
                    "query": "音乐 篮球",
                    "minimum_should_match": "70%"
                }
            }
        },
        "highlight": {
            "fields": {
                "hobby": {}
            }
        }
    }

      4.组合搜索

        在搜索时,也可以使用过滤器中讲过的bool组合查询,示例:

        POST /fan/person/_search

    {
        "query": {
            "bool": {
                "must": {
                    "match": {
                        "hobby": "篮球"
                    }
                },
                "must_not": {
                    "match": {
                        "hobby": "音乐"
                    }
                },
                "should": [{
                    "match": {
                        "hobby": "游泳"
                    }
                }]
            }
        },
        "highlight": {
            "fields": {
                "hobby": {}
            }
        }
    }

          上面搜索的意思是:搜索结果中必须包含篮球,不能包含音乐,如果包含了游泳,那么它的相似度更高。

        评分的计算规则:
          bool 查询会为每个文档计算相关度评分 _score , 再将所有匹配的 must 和 should 语句的分数 _score 求和,最后除以 must 和 should 语句的总数。
          must_not 语句不会影响评分; 它的作用只是将不相关的文档排除。

        默认情况下,should中的内容不是必须匹配的,如果查询语句中没有must,那么就会至少匹配其中一个。当然了,也可以通过minimum_should_match参数进行控制,该值可以是数字也可以的百分比。

    {
        "query": {
            "bool": {
                "should": [{
                        "match": {
                            "hobby": "游泳"
                        }
                    },
                    {
                        "match": {
                            "hobby": "篮球"
                        }
                    },
                    {
                        "match": {
                            "hobby": "音乐"
                        }
                    }
                ],
                "minimum_should_match": 2
            }
        },
        "highlight": {
            "fields": {
                "hobby": {}
            }
        }
    }

          minimum_should_match为2,意思是should中的三个词,至少要满足2个。

      5.权重

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

          搜索关键字为“游泳篮球”,如果结果中包含了“音乐”权重为10,包含了“跑步”权重为2。

          POST /fan/person/_search

    {
        "query": {
            "bool": {
                "must": {
                    "match": {
                        "hobby": {
                            "query": "游泳篮球",
                            "operator": "and"
                        }
                    }
                },
                "should": [{
                        "match": {
                            "hobby": {
                                "query": "音乐",
                                "boost": 10
                            }
                        }
                    },
                    {
                        "match": {
                            "hobby": {
                                "query": "跑步",
                                "boost": 2
                            }
                        }
                    }
                ]
            }
        },
        "highlight": {
            "fields": {
                "hobby": {}
            }
        }
    }
  • 相关阅读:
    Application.Current的使用
    .NET中资源文件的使用
    PMP模拟试题与解析(七)
    PMP模拟试题与解析(四)
    RMAN命令简介
    数据库备份和恢复概述
    ORA-14402: updating partition key column would cause a partition change
    RMAN概述
    PLS-00642: local collection types not allowed in SQL statements
    SFTP(Secure File Transfer Protocol)安全的文件传输协议的使用
  • 原文地址:https://www.cnblogs.com/roadlandscape/p/12571890.html
Copyright © 2020-2023  润新知