zoukankan      html  css  js  c++  java
  • Elastic Stack:es 搜索入门

    一.搜索

    搜索所有:

    GET /index/_search
    

     返回结果解释:

    took:耗时几毫秒

    time_out:是否超时,默认不超时,设置超时时间后,当搜索超时后,停止搜索,并返回已经搜索到的数据。

        配置方法:search.default_search_timeout

    _shards:到几个分片搜索,成功几个,跳过几个,失败几个。

    hits.total:查询结果的数量

    hit.max_score:对搜索的相关度的匹配分数,分数越高,就越匹配

    hit.hits:包含搜索结果document的所有详细数据。

    传参:

    GET /book/_search?q=name:java&sort=price:desc
    

     相当于oracle中:select * from book where name like '%java%' order by price desc

    多索引搜索:一次性搜索多个index和多个type下的数据

    GET /index1,index2/_search:同时搜索两个index下的数据
    GET /index*/_search:按照通配符去匹配多个索引
    

     应用场景:生产环境log索引可以按照日期分开。

      log_201911

        log_201912

        log_202001

    二.分页搜索

    #从第四条数据开始搜索一页,一页两条
    GET /book/_search?from=3&size=2
    

     deep paging:根据相关度评分倒排序,所以分页过深,协调节点会将大量数据聚合分析。

       deep paging性能低,应该较少使用。

    三.query string基础语法

      GET /book/_search?q=name:java 搜索name中包含java关键字的

      GET /book/_search?q=+name:java 搜索name中包含java关键字的

      GET /book/_search?q=-name:java 搜索name中不包含java关键字的

    _all metadata:

      GET /book/_search?q=java,直接搜索所有的field,任意一个field包含java,都可以搜索出来。

    四.query DSL

    DSL:domain specified language 特定领域的语言,es特有的搜索语言,可以在请求体重携带搜索条件。

    查询全部:

    GET /book/_search
    {
      "query": { "match_all": {} }
    }
    

     排序

    GET /book/_search 
    {
        "query" : {
            "match" : {
                "name" : " java"
            }
        },
        "sort": [
            { "price": "desc" }
        ]
    }
    

    分页:

    GET  /book/_search 
    {
      "query": { "match_all": {} },
      "from": 0,
      "size": 1
    }
    

     指定返回字段:

    GET /book/_search 
    {
      "query": { "match_all": {} },
      "_source": ["name", "studymodel"]
    }
    

    DSL语法:

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

    搜索需求:title必须包含elasticsearch,content可以包含elasticsearch也可以不包含,author_id必须不为111 

    GET /website/_doc/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "title": "elasticsearch"
              }
            }
          ],
          "should": [
            {
              "match": {
                "content": "elasticsearch"
              }
            }
          ],
          "must_not": [
            {
              "match": {
                "author_id": 111
              }
            }
          ]
        }
      }
    }
    

     全文检索: 

    match_all查询全部:

    GET /book/_search
    {
        "query": {
            "match_all": {}
        }
    }
    

      match:全文检索

    GET /book/_search
    {
    	"query": { 
    		"match": { 
    			"description": "java程序员"
    		}
    	}
    }
    

     multi_match:在多个属性中去查

    GET /book/_search
    {
      "query": {
        "multi_match": {
          "query": "java程序员",
          "fields": ["name", "description"]
        }
      }
    }
    

     range_query 范围查询

    GET /book/_search
    {
      "query": {
        "range": {
          "price": {
            "gte": 80,
    	"lte": 90
          }
        }
      }
    }
    

     term: 字段为keyword时,存储和搜索都不分词

    例子:查询分词为"java程序员"

    GET /book/_search
    {
      "query": {
        "term": {
          "description": "java程序员"
        }
      }
    }
    

    terms:

    例子:同个一个字段中,查询同时包含"search","full_text","nosql"三个分词的文档

    GET /book/_search
    {
        "query": { "terms": { "tag": [ "search", "full_text", "nosql" ] }}
    }

    exists:含有某些字段的文档

    例子:查询包含price字段的文档

    GET /_search
    {
        "query": {
            "exists": {
                "field": "price"
            }
        }
    }
    

    fuzzy:返回包含与搜索词类似的词的文档,该词由Levenshtein编辑距离度量。 

    有一下几种情况:

    • 更改角色(box→fox)

    • 删除字符(aple→apple)

    • 插入字符(sick→sic)

    • 调换两个相邻字符(ACT→CAT)

    GET /book/_search
    {
        "query": {
            "fuzzy": {
                "description": {
                    "value": "jave"
                }
            }
        }
    }

    ids:根据文档id进行查询

    GET /book/_search
    {
        "query": {
            "ids" : {
                "values" : ["1", "4", "100"]
            }
        }
    }
    

    prefix:前缀查询

    GET /book/_search
    {
        "query": {
            "prefix": {
                "description": {
                    "value": "spring"
                }
            }
        }
    }
    

    regexp:正则查询

    GET /book/_search
    {
        "query": {
            "regexp": {
                "description": {
                    "value": "j.*a",
                    "flags" : "ALL",
                    "max_determinized_states": 10000,
                    "rewrite": "constant_score"
                }
            }
        }
    }
    

     五.filter

    需求:用户查询description中有"java程序员",并且价格大于80小于90的数据。

    filter:对全文检索的结果进行过滤

    GET /book/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "description": "java程序员"
              }
            }
          ],
          "filter": {
            "range": {
              "price": {
                "gte": 80,
    		     "lte": 90
              }
            }
          }
        }
      }
    }
    

    filter与query对比:

      filter,仅仅只是按照搜索条件过滤出需要的数据而已,不计算任何相关度分数,对相关度没有任何影响。

      query,会去计算每个document相对于搜索条件的相关度,并按照相关度进行排序。

      filter,不需要计算相关度分数,不需要按照相关度分数进行排序,同时还有内置的自动cache最常使用filter的数据

      query,相反,要计算相关度分数,按照分数进行排序,而且无法cache结果

    当只写"filter",不写" must",就会报错,只过滤的正确写法如下,加上constant_score。

    GET /book/_search
    {
      "query": {
        "constant_score": {
          "filter": {
            "term": {
              "description": "java"
            }
          }
        }
      }
    }
    定制排序规则:
    GET /book/_search
    {
      "query": {
        "constant_score": {
          "filter": {
            "term": {
              "description": "java"
            }
          }
        }
      },
      "sort": [
        {
          "price": {
            "order": "desc"
          }
        }
      ]
    }

    text field排序问题:

    如果对一个text field进行排序,结果往往不准确,因为分词后是多个单词,再排序就不是我们想要的结果了。

    方案一:通常解决方案是,将一个text field建立两次索引,一个分词,用来进行搜索;一个不分词,用来进行排序。

    方案二:在创建索引的时候设置:fielddate:true

    六.执行计划

    一般用在那种特别复杂庞大的搜索下,比如你一下子写了上百行的搜索,这个时候可以先用validate api去验证一下,搜索是否合法。

    合法以后,explain就像mysql的执行计划,可以看到搜索的目标等信息。

    GET /book/_validate/query?explain
    {
        "query": {
            "fuzzy": {
                "description": {
                    "value": "jave"
                }
            }
        }
    }
    

     

    七.srcoll分批查询

    场景:下载某一个索引中1亿条数据,到文件或是数据库。不能一下全查出来,系统内存溢出。所以使用scoll滚动搜索技术,一批一批查询。

    scoll搜索会在第一次搜索的时候,保存一个当时的视图快照,之后只会基于该旧的视图快照提供数据搜索,如果这个期间数据变更,是不会让用户看到的

    每次发送scroll请求,我们还需要指定一个scoll参数,指定一个时间窗口,每次搜索请求只要在这个时间窗口内能完成就可以了。

    第一次搜索:

    GET /book/_search?scroll=1m
    {
      "query": {
        "match_all": {}
      },
      "size": 3
    }
    

     返回:

    {
      "_scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAMOkWTURBNDUtcjZTVUdKMFp5cXloVElOQQ==",
      "took" : 3,
      "timed_out" : false,
      "_shards" : {
        "total" : 1,
        "successful" : 1,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : {
          "value" : 3,
          "relation" : "eq"
        },
        "max_score" : 1.0,
        "hits" : [
         
        ]
      }
    }
    

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

    GET /_search/scroll
    {
        "scroll": "1m", 
        "scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAMOkWTURBNDUtcjZTVUdKMFp5cXloVElOQQ=="
    }
  • 相关阅读:
    docker基于commit命令创建支持ssh服务的镜像
    CentOS 6.5 下Nginx服务的安装与配置
    CentOS 6.5 下搭建vsftp服务
    CentOS 6.5 下搭建FastDFS服务
    CentOS 6.5 下Nginx服务的安装与配置
    CentOS 6.5 下搭建NTP服务器
    CentOS6.5 下Haproxy服务的安装与配置
    CentOS 6.5 下HeartBeat的安装与配置
    CentOS 6.5 下keepalived服务的配置
    IDE vscode识别webpack中alias配置路径
  • 原文地址:https://www.cnblogs.com/wwjj4811/p/13094884.html
Copyright © 2011-2022 走看看