zoukankan      html  css  js  c++  java
  • Elasticsearch 搜索引擎

    1. 搜索结果中的一些词的含义

    took:整个搜索请求花费了多少毫秒;

    hits.total:本次搜索,返回了几条结果;

    hits.max_score:本次搜索的所有结果中,最大的相关度分数是多少,每一条document对于search的相关度,越相关,_score分数越大,排位越靠前;

    hits.hits:默认查询前10条数据,完整数据,_score降序排序;

    shards:shards fail的条件(primary和replica全部挂掉),不影响其他shard。默认情况下来说,一个搜索请求,会打到一个index的所有primary shard上去,每个primary shard都可能会有一个或多个replic shard,所以请求也可以到primary shard的其中一个replica shard上去;

    timeout:默认无timeout,latency平衡completeness,手动指定timeout,timeout查询执行机制;

    GET /_search?timeout=10m 

    timeout查询执行机制指每个shard在timeout时间内,将搜索的部分数据(也可以是全部数据)直接返回给client程序,而不用等到所有的查询结果都查询出来再返回;

    2. multi-index和multi-type搜索模式

    /_search:所有索引,所有type下的所有数据都搜索出来
    /*1,*2/_search:按照通配符去匹配多个索引
    /index1,index2/type1,type2/_search:搜索多个index下的多个type的数据
    /_all/type1,type2/_search:_all,可以代表搜索所有index下的指定type的数据

    3.搜索原理初步

    client会把一个请求打到所有primary shard上去执行,因为每个shard都包含了部分数据,所以每个shard都可能包含了搜索请求的结果,因为每个primary shard 都包含replica shard,所以请求也会打到replica shard上。

    4.分布搜索

    GET /_search?size=10&from=20

    5.deep paging 问题 

    简单说,就是搜溹的特别深;

    带来的问题:coordinate node 上需要保存大量的数据,还需进行大量数据的排序,排序之后再取出对应的那一页,这个过程耗费网络带宽,耗费内存和CPU;

    6.query string 基础语法

    GET /test_index/test_type/_search?q=test_field:test
    GET /test_index/test_type/_search?q=+test_field:test  必须包含和上面一样
    GET /test_index/test_type/_search?q=-test_field:test   必须不包含

    _all metadata的原理和作用:

    我们并不是对document中的每一个field进行一个一个的搜索,_all元数据在建立索引的时候,我们插入一个document,里面包含了多个field,此时es会将里面多个field的值用字符串拼接起来,同时建立索引,我们在不对特定的field的进行搜索的时候,就会从_all field 中进行搜溹;

    7.mapping

    定义:自动或手动为index中的type建立的一种数据结构和相关配置,简称为mapping;mapping就是index的type的元数据,每个type都有一个自己的mapping,决定了数据类型,建立倒排索引的行为,还有进行搜索的行为;

    mapping建立过程:

        1)往es里面直接插入数据,es会自动建立索引,同时建立type以及对应的mapping;
        2)mapping中就自动定义了每个field的数据类型;
        3)不同的数据类型(比如说text和date),可能有的是exact value,有的是full text;
        4)exact value,在建立倒排索引的时候,分词时是将整个值一起作为一个关键词建立到倒排索引中的;full text,会经历处理,分词,normaliztion,才会建立到倒排索引中;
        5)exact value和full text类型的field就决定了,在一个搜索过来的时候,对exact value field或者是full text field进行搜索的行为也是不一样的,会跟建立倒排索引的行为保持一致;比如说exact value搜索的时候,就是直接按照整个值进行匹配,full text,会进行分词和normalization再去倒排索引中去搜索;
        6)可以用es的dynamic mapping,让其自动建立mapping,包括自动设置数据类型;也可以提前手动创建index和type的mapping,自己对各个field进行设置,包括数据类型,包括索引行为,包括分词器等;

    dynamic mapping,自动为我们建立index,创建type,以及type对应的mapping,mapping中包含了每个field对应的数据类型,以及如何分词等设置;

    true or false --> boolean
    123 --> long
    123.45 --> double
    2017-01-01 --> date
    "hello world" --> string/text

    mapping的查看:GET /index/_mapping/type

    只能创建index时手动建立mapping,或者新增field mapping,但是不能update field mapping;

    PUT /website
    {
      "mappings": {
        "article": {
          "properties": {
            "author_id": {
              "type": "long"
            },
            "title": {
              "type": "text",
              "analyzer": "english"
            },
            "content": {
              "type": "text"
            },
            "post_date": {
              "type": "date"
            },
            "publisher_id": {
              "type": "text",
              "index": "not_analyzed"
            }
          }
        }
      }
    }

    es自动建立mapping的时候,设置了不同的field不同的data type。不同的data type的分词、搜索等行为是不一样的。所以出现了_all field和date field的搜索表现完全不一样。

    不同类型的field,可能有的就是full text,有的就是exact value;

    8.倒排索引

    在建立倒排索引前,会先执行一个操作,对拆分出来的单词进行处理(normalization),来提升搜索时能搜到的概率;

    9. 分词器

    内置的分词器:standard analyzer,simple analyzer,whitespace analyzer,language analyzer

    分词器查看 GET /_analyze

    10. http协议中get是否可以带上request body

    HTTP协议,一般不允许get请求带上request body,但是因为get更加适合描述查询数据的操作,因此还是这么用了;

    GET /_search?from=0&size=10

    POST /_search
    {
    "from":0,
    "size":10
    }

    11. Query DSL的基本语法

    {
         QUERY_NAME: {
                  ARGUMENT: VALUE,
                  ARGUMENT: VALUE,...
            }
    }

    {
            QUERY_NAME: {
               FIELD_NAME: {
                 ARGUMENT: VALUE,
                 ARGUMENT: VALUE,...
                }
           }
    }

    GET /test_index/test_type/_search 
    {
      "query": {
        "match": {
          "test_field": "test"
        }
      }
    }
    

    组合搜索条件:

    搜索需求:title必须包含elasticsearch,content可以包含elasticsearch也可以不包含,author_id必须不为111
    GET /website/article/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "title": "elasticsearch"
              }
            }
          ],
          "should": [
            {
              "match": {
                "content": "elasticsearch"
              }
            }
          ],
          "must_not": [
            {
              "match": {
                "author_id": 111
              }
            }
          ]
        }
      }
    }

    12. filter实例

    filter,仅仅只是按照搜索条件过滤出需要的数据而已,不计算任何相关度分数,对相关度没有任何影响;
    query,会去计算每个document相对于搜索条件的相关度,并按照相关度进行排序;

    一般来说,如果你是在进行搜索,需要将最匹配搜索条件的数据先返回,那么用query;如果你只是要根据一些条件筛选出一部分数据,不关注其排序,那么用filter
    除非是你的这些搜索条件,你希望越符合这些搜索条件的document越排在前面返回,那么这些搜索条件要放在query中;如果你不希望一些搜索条件来影响你的document排序,那么就放在filter中即可;

    filter与query性能对比:
    filter,不需要计算相关度分数,不需要按照相关度分数进行排序,同时还有内置的自动cache最常使用filter的数据;
    query,相反,要计算相关度分数,按照分数进行排序,而且无法cache结果

    GET /company/employee/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "join_date": "2016-01-01"
              }
            }
          ],
          "filter": {
            "range": {
              "age": {
                "gte": 30
              }
            }
          }
        }
      }
    }

    13. query搜索语法

    1)、match all
    
    GET /_search
    {
        "query": {
            "match_all": {}
        }
    }
    
    2)、match
    
    GET /_search
    {
        "query": { "match": { "title": "my elasticsearch article" }}
    }
    
    3)、multi match
    
    GET /test_index/test_type/_search
    {
      "query": {
        "multi_match": {
          "query": "test",
          "fields": ["test_field", "test_field1"]
        }
      }
    }
    
    4)、range query
    
    GET /company/employee/_search 
    {
      "query": {
        "range": {
          "age": {
            "gte": 30
          }
        }
      }
    }
    
    5)、term query
    
    GET /test_index/test_type/_search 
    {
      "query": {
        "term": {
          "test_field": "test hello"
        }
      }
    }
    
    6)、terms query
    
    GET /_search
    {
        "query": { "terms": { "tag": [ "search", "full_text", "nosql" ] }}
    }

    14. 快速验证错误原因

    GET /test_index/test_type/_validate/query?explain

    {
    "query": {
    "math": {
    "test_field": "test"
    }
    }
    }

    15.排序规则

    1)默认情况下是有按照score进行降序排序的,对比没有score时(filter),可以使用constant_score

    GET /_search
    {
        "query" : {
            "constant_score" : {
                "filter" : {
                    "term" : {
                        "author_id" : 1
                    }
                }
            }
        }
    }

    2) 定制排序规则:

    GET /company/employee/_search 
    {
      "query": {
        "constant_score": {
          "filter": {
            "range": {
              "age": {
                "gte": 30
              }
            }
          }
        }
      },
      "sort": [
        {
          "join_date": {
            "order": "asc"
          }
        }
      ]
    }

    16. TF-IDF算法

    Term frequency(TF):搜索文本中的各个词条在field文本中出现了多少次,出现次数越多,就越相关;

    Inverse document frequency(IDF):搜索文本中的各个词条在整个索引的所有文档中出现了多少次,出现的次数越多,就越不相关;

    Field-length norm:field长度,field越长,相关度越弱;

    1)_score是如何被计算出来的?

    GET /test_index/test_type/_search?explain
    {
      "query": {
        "match": {
          "test_field": "test hello"
        }
      }
    }

    2)分析一个document是如何被匹配上的

    GET /test_index/test_type/6/_explain
    {
      "query": {
        "match": {
          "test_field": "test hello"
        }
      }
    }

    17. doc values

    搜索的时候,要依靠倒排索引;排序的时候,需要依靠正排索引(doc values)

    doc values是被保存在磁盘上的,此时如果内存足够,os会自动将其缓存在内存中,性能还是会很高;如果内存不足够,os会将其写入磁盘上;

    18. query phase

    1)搜索请求发送到某一个coordinate node,构建一个priority queue,长度以paging操作from和size为准,默认为10;
    2)coordinate node将请求转发到所有shard,每个shard本地搜索,并构建一个本地的priority queue;
    3)各个shard将自己的priority queue返回给coordinate node,并构建一个全局的priority queue;

    replica shard如何提升搜索吞吐量?

    一次请求要打到所有shard的一个replica/primary上去,如果每个shard都有多个replica,那么同时并发过来的搜索请求可以同时打到其他的replica上去;

    19. fetch phase

    1)在query phase结束时,coordinate node构建完全局priority queue之后,就发送mget请求去所有shard上获取对应的document;
    2)各个shard将document返回给coordinate node;
    3)coordinate node将合并后的document结果返回给client客户端;

    一般搜索,如果不加from和size,就默认搜索前10条,按照_score排序;

    20. 参数preference,search_type

    1)决定了哪些shard会被用来执行搜索操作

    _primary, _primary_first, _local, _only_node:xyz, _prefer_node:xyz, _shards:2,3

    2)bouncing results问题

    两个document排序,field值相同;不同的shard上,可能排序不同;每次请求轮询打到不同的replica shard上;每次页面上看到的搜索结果的排序都不一样。这就是bouncing result,也就是跳跃的结果。

    解决方案就是将preference设置为一个字符串,比如说user_id,让每个user每次搜索的时候,都使用同一个replica shard去执行,就不会看到bouncing results;

    3)search_type

    default:query_then_fetch
    dfs_query_then_fetch,可以提升revelance sort精准度

    21. scoll技术

    scoll滚动查询,一批一批的查,直到所有数据都查询完处理完;

    scoll搜索会在第一次搜索的时候,保存一个当时的视图快照,之后只会基于该旧的视图快照提供数据搜索,如果这个期间数据变更,是不会让用户看到的;
    采用基于_doc进行排序的方式,性能较高;
    每次发送scroll请求,我们还需要指定一个scoll参数,指定一个时间窗口,每次搜索请求只要在这个时间窗口内能完成就可以了;

    GET /test_index/test_type/_search?scroll=1m
    {
    "query": {
    "match_all": {}
    },
    "sort": [ "_doc" ],
    "size": 3
    }

    获得的结果会有一个scoll_id,下一次再发送scoll请求的时候,必须带上这个scoll_id

    GET /_search/scroll
    {
    "scroll": "1m", 
    "scroll_id" : "DnF1ZXJ5VGhlbkZldGNoBQAAAAAAACxeFjRvbnNUWVZaVGpHdklqOV9zcFd6MncAAAAAAAAsYBY0b25zVFlWWlRqR3ZJajlfc3BXejJ3AAAAAAAALF8WNG9uc1RZVlpUakd2SWo5X3NwV3oydwAAAAAAACxhFjRvbnNUWVZaVGpHdklqOV9zcFd6MncAAAAAAAAsYhY0b25zVFlWWlRqR3ZJajlfc3BXejJ3"
    }
  • 相关阅读:
    GhostBSD 3.0RC3,基于GNOME的FreeBSD
    Nagios 3.4.3 发布,企业级监控系统
    Jolokia 1.0.6 发布, JMX远程访问方法
    微软希望开发人员不要使 WebKit 成为新版 IE6
    Kwort Linux 3.5 正式版发布
    EJDB 1.0.24 发布,嵌入式 JSON 数据库引擎
    Pale Moon 15.3 Firefox“苍月”优化版发布
    Galera Load Balancer 0.8.1 发布
    SmartSVN V7.5 正式发布
    PostgresQL建立索引如何避免写数据锁定
  • 原文地址:https://www.cnblogs.com/ntbww93/p/9815740.html
Copyright © 2011-2022 走看看