美文网首页elasticsearch
ElasticSearch(四):Search运行机制

ElasticSearch(四):Search运行机制

作者: 采风JS | 来源:发表于2018-11-21 17:36 被阅读31次

    一 Query-then-Fetch

    • 执行流程
    分布式三个节点node1/node2/node3,分片分别为p1/p2/p3,副本分别为r1/r2/r3,node3接受请求GET  text_index/_search,执行流程如下:
    ----query phase
    1-node3在6个主副分片上随机选择3个分片,发送search request请求;
    2-被选中的3个分片分别执行查询,返回from+size个文档id和排序值;
    3-node3整合3个分片返回的3份from+size个文档id,根据排序值选取from到from+size的文档id;
    ----fetch phase
    4-node3根据query阶段获取的文档id列表到对应的分片上获取文档详细数据;
    

    二 相关性算分

    • 相关性算分在shard与shard间相互独立,即同一个term的IDF值在不同的shard上不相同;
    • 文档数量不多时,导致相关性算分严重不准确;
    • 解决方案一,设置分片数为1,文档数量不多时可以考虑;
    • 解决方案二,DFS Query-then-Fetch 拿到所有文档后重新完整计算一次相关性得分,极度耗费资源;
    GET test_search_relevance/_search?search_type=dfs_query_then_fetch
    

    三 排序

    • sort自定义排序规则
    GET test_search_index/_search
    {
      "query":{
        "match": {
          "username": "alfred"
        }
      },
      "sort": [
        {
          "birth": "desc" ##按照生日降序排序
        },
        {
          "_score": "desc" ##按章相关性算分降序排序
        },
        {
          "_doc": "desc" ##按照文档内部id,与创建顺序有关
        }
      ]
    }
    
    • text和keyword
      fielddata默认关闭,按照text类型排序报错,使用keyword类型排序;
    GET test_search_index/_search
    {
      "sort": [
        {
          "username": "asc" ##报错,Fielddata is disabled on text fields by default
        }
      ]
    }
    GET test_search_index/_search
    {
      "sort":{
        "username.keyword":"desc" ##可以排序
      }
    }
    
    • fielddata
      默认关闭,可以随时打开和关闭,只对text类型有用,一般在对分词做聚合分析时开启;
    ## fielddata:默认关闭
    PUT test_search_index/_mapping/doc
    {
      "properties": {
        "job":{
          "type":"text",
          "fielddata": true
        }
      }
    }
    ## 仅对text字段有效
    PUT test_search_index/_mapping/doc
    {
      "properties": {
        "username":{
          "type":"text",
          "fielddata": false
        },
        "age":{
          "type":"long",
          "fielddata": true
        }
      }
    }
    
    • doc values
      默认启用,创建索引时可以关闭,若再次开启,需要reindex操作;
    PUT test_doc_values1/
    {
      "mappings": {
        "doc": {
          "properties": {
            "username": {
              "type": "keyword",
              "doc_values": false
            }
          }
        }
      }
    }
    PUT test_doc_values/doc/1
    {
      "username":"alfred",
      "hobby":"basketball"
    }
    ##已经关闭doc values不能开启
    GET test_doc_values/_search
    {
      "sort":"username"
    }
    ##可以启用
    GET test_doc_values/_search
    {
      "sort":"hobby"
    }
    

    四 分页

    • from/size
      在数据分片存储情况下如何获取前1000个文档?
      每个分片上获取1000个文档,然后聚合所有分片上的1000个文档最后排序取前1000个文档;
      Es通过index.max_result_window限定最多到10000条数据;
    GET test_search_index/_search
    {
      "from":10000, ##Result window is too large, from + size must is less than or equal to [10000] but [10002]
      "size":2
    }
    
    • scroll
      遍历文档集,以快照的方式避免深度分页问题;
      不能用来做实时搜素,因为数据不是实时的;
      新添加的文档不能被 使用;
    GET test_search_index/_search?scroll=5m
    {
      "size":1
    }
    POST _search/scroll
    {
      "scroll" : "5m", 
      ##调用时使用上一次返回时的scroll_id
      "scroll_id": "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAABswWX3FLSTZFOF9URFdqWHlvX3gtYmhtdw=="
    }
    ##新添加的文档在scroll中不能使用
    PUT test_search_index/doc/10
    {
      "username":"doc10"
    }
    
    • search_after
      避免深度分页性能问题,提供实时的下一页文档获取功能;
      不能使用from,只能下一页;
    ##第一步,指定sort值,且为唯一
    GET test_search_index/_search
    {
      "size":1,
      "sort":{
        "age":"desc",
        "_id":"desc"
      }
    }
    ##第二步,使用上一次查询的最后一个文档的sort值进行查询
    GET test_search_index/_search
    {
      "size":1,
      "search_after":[23,"4"],
      "sort":{
        "age":"desc",
        "_id":"desc"
      }
    }
    

    相关文章

      网友评论

        本文标题:ElasticSearch(四):Search运行机制

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