美文网首页
Full Text Search

Full Text Search

作者: 潘大的笔记 | 来源:发表于2019-10-30 17:14 被阅读0次

    全文搜索

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

    基于词项与基于全文

    1、基于词项的查询
    term或fuzzy这样的底层查询不需要分析阶段,它们对单个词项进行操作。
    只需要在倒排索引中查找准确词项。
    2、基于全文的查询
    match或query_string这样的查询是高层查询,它们了解字段映射的信息:
    -如果查询date或integer字段,它们会将查询字符串分别作为date或integer对待。
    -如果查询not_analyzed的精确值字符串字段,它们会将整个查询字符串作为单个词项对待。
    -如果查询analyzed的全文字段,它们会先将查询字符串传递到一个合适的分析器,然后生成一个供查询的词项列表。
    一旦组成了词项列表,这个查询会对每个词项逐一执行底层的查询。

    匹配查询

    match是个核心查询、高级全文查询,既能处理全文字段,又能处理精确字段。
    它是首选的查询方式
    单个词查询

    GET /my_index/my_type/_search
    {
        "query": {
            "match": {
                "title": "QUICK!"
            }
        }
    }
    

    es执行上面这个match查询的步骤是:
    1、检查字段类型。
    title字段是一个string类型的全文字段,意味着查询字符串本身也应该被分析。
    2、分析查询字符串。
    传入标准分析中,输出的结果是单个项quick。因为是一个单词项,所以match查询执行的单个底层term查询
    3、查询匹配文档
    4、为每个文档评分

    多词查询

    GET /my_index/my_type/_search
    {
        "query": {
            "match": {
                "title": "BROWN DOG!"
            }
        }
    }
    

    与单词项查询类似,只不过term会被执行多次(多个term包入一个bool中)
    多词查询默认情况下,只要匹配一个词就会被匹配(or)

    GET /my_index/my_type/_search
    {
        "query": {
            "match": {
                "title": {      (1)
                    "query":    "BROWN DOG!",
                    "operator": "and"
                }
            }
        }
    }
    

    使用operator可以修改成and,多个词都被匹配,文档才会被匹配
    还可以使用"minimum_should_match": "75%"75%的词项被匹配,文档就会被匹配
    但是假如只有三个词项,75%会被自动阶段成66.6%

    组合查询

    在组合过滤器中,使用bool进行组合,在查询中bool也有类似的功能,只有一个重要的区别。
    过滤器是非黑即白的,然而查询会计算文档的相关程度。

    GET /my_index/my_type/_search
    {
      "query": {
        "bool": {
          "must":     { "match": { "title": "quick" }},
          "must_not": { "match": { "title": "lazy"  }},
          "should": [
                      { "match": { "title": "brown" }},
                      { "match": { "title": "dog"   }}
          ]
        }
      }
    }
    

    上述查询must和must_not与bool过滤器的工作方式非常相似。
    区别在于两个should语句:不必包含,但是包含了就更相关了
    bool查询会为每个文档计算相关度评分_score,再将所有匹配的must和should语句的分数_score求和,最后除以must和should语句的总数。
    must_not不影响评分,只是将不相关的文档排除。
    默认情况下没有should语句是必须匹配的,但是当没有must语句的时候。至少有一个should语句必须匹配
    类似控制match查询的精度一样,minimum_should_match也可以控制should语句的精度,可以是数字,也可以是百分比

    GET /my_index/my_type/_search
    {
      "query": {
        "bool": {
          "should": [
            { "match": { "title": "brown" }},
            { "match": { "title": "fox"   }},
            { "match": { "title": "dog"   }}
          ],
          "minimum_should_match": 2
        }
      }
    }
    

    查询语句提升权重

    GET /_search
    {
        "query": {
            "bool": {
                "must": {
                    "match": {
                        "content": { 
                            "query":    "full text search",
                            "operator": "and"
                        }
                    }
                },
                "should": [ 
                    { "match": { "content": "Elasticsearch" }},
                    { "match": { "content": "Lucene"        }}
                ]
            }
        }
    }
    

    这个查询中content字段必须包含full/text/search,如果包含 Elasticsearch/Lucene会获得更高的评分。
    我们想要Elasticsearch/Lucene的权重有些变化,可以使用boost(默认值是1,取值范围>0),boost的提升或者降低不是线性的。有一个归一化的过程

    GET /_search
    {
        "query": {
            "bool": {
                "must": {
                    "match": {  
                        "content": {
                            "query":    "full text search",
                            "operator": "and"
                        }
                    }
                },
                "should": [
                    { "match": {
                        "content": {
                            "query": "Elasticsearch",
                            "boost": 3 
                        }
                    }},
                    { "match": {
                        "content": {
                            "query": "Lucene",
                            "boost": 2 
                        }
                    }}
                ]
            }
        }
    }
    

    控制分析

    可以为字段指定分析器,也可以使用type/index/node的默认配置
    可以使用analyze API来分析单词

    GET /my_index/_analyze
    {
      "field": "my_type.title",   (1)
      "text": "Foxes"
    }
    
    GET /my_index/_analyze
    {
      "field": "my_type.english_title",   (2)
      "text": "Foxes"
    }
    

    1使用默认的standard标准分析器,返回词项foxes
    2使用english英语分析器,返回词项fox
    意味着使用term查询精确项fox时,english_title字段会匹配,但title字段不会
    可以使用validate-query API来查看高层查询(例如match)的分析行为

    GET /my_index/my_type/_validate/query?explain
    {
        "query": {
            "bool": {
                "should": [
                    { "match": { "title":         "Foxes"}},
                    { "match": { "english_title": "Foxes"}}
                ]
            }
        }
    }
    

    返回语句的explanation结果:

    (title:foxes english_title:fox)
    

    默认分析器

    按照层级顺序查找分析器,直到找到能够使用的分析器。
    索引时的顺序如下
    1、字段映射里定义的analyzer
    2、索引设置中名为default的分析器,默认为standard
    3、standard标准分析器
    查询时的顺序如下:
    1、查询自己定义的analyzer
    2、字段映射里定义的analyzer
    3、索引设置中名为default的分析器,默认为standard
    4、standard标准分析器
    索引时和搜索时使用不同的分析器是合理,例如为同义词建索引,但在搜索时我们不需要搜索所有同义词。
    为了区分,es支持一个可选的search_analyzer映射,以及一个等价的default_search映射
    搜索时,完整顺序如下:
    1、查询自己定义的analyzer
    2、字段映射里定义的search_analyzer
    3、字段映射里定义的analyzer
    4、索引设置中名为default_search的分析器,默认为standard
    5、索引设置中名为default的分析器,默认为standard
    6、standard标准分析器

    被破坏的相关度!!!

    用户索引了一些文档,运行一个简单的查询,然后发现明显低相关度的结果出现在高相关度结果之上。
    由于相似度算法TF/IDF,词频/逆向文档频率
    词频是某个词在“当前被查询文档”里面某个字段中出现的频率
    逆向文档频率是将某个词在索引内“所有文档”出现的百分数
    需要注意的是,es不会计算索引内所有文档的IDF,只会计算分片的本地IDF。
    数据较少时,不同分片的IDF差异较大,就会导致相关度被破坏
    可以在搜索请求后添加?search_type=dfs_query_then_fetch,dfs 是指 分布式频率搜索(Distributed Frequency Search)分别获得每个分片本地的IDF,然后根据结果再计算全局IDF
    实际上!完全没有必要使用,只要有足够的数据就能保证词频是均匀分布的。

    相关文章

      网友评论

          本文标题:Full Text Search

          本文链接:https://www.haomeiwen.com/subject/sanovctx.html