• Elasticsearch学习系列三(搜索案例实战)


    Query DSL

    Es提供了基于JSON的完整查询DSL(Domain Specific Language 特定域的语言)来定义查询。将查询DSL视为查询的AST(抽象语法树)。它由两种子句组成:

    • 叶子查询子句

    叶子查询子句,在特定域中寻找特定的值,如match、term或range查询

    • 复合查询子句

    复合查询子句包装其他叶子查询或复合查询,并用于以逻辑方式组合多个查询。如bool、dis_max、constant_score查询

    1. 查询所有

    POST /索引名称/_search
    {
      "query":{
        "match_all": {}
      }
    }
    

    查询结果示例:

    {
      "took" : 1,
      "timed_out" : false,
      "_shards" : {
        "total" : 1,
        "successful" : 1,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : {
          "value" : 3,
          "relation" : "eq"
        },
        "max_score" : 1.0,
        "hits" : [
          {
            "_index" : "test-demo1",
            "_type" : "_doc",
            "_id" : "1",
            "_score" : 1.0,
            "_source" : {
              "name" : "百度3",
              "job" : "运营",
              "amt" : "3000.34",
              "logo" : "http://www.lgstatic.com/ttasdf2",
              "createTime" : "20220303230000"
            }
          }
          ...省略2条数据
        ]
      }
    }
    
    
    • took:查询花费时间,单位是毫秒
    • time_out:是否超时
    • _shards:分片信息
    • hits:搜索结果总览对象
      • total:搜索到的总条数
      • max_score:所有结果中文档得分的最高分
      • hits:搜索结果的文档对象数组,每个元素是一条搜索到的文档信息
        • _index:索引库
        • _type:文档类型
        • _id:文档id
        • _score:文档得分
        • _source:文档的源数据

    2. 全文搜索

    全文搜索能够搜索已分析的文本字段,如电子邮件正文、商品描述等。

    先造一些测试数据:

    PUT /item
    {
      "settings": {},
      "mappings": {
        "properties": {
          "title": {
            "type": "text",
            "analyzer": "ik_max_word"
          },
          "images": {
            "type": "keyword"
          },
          "price": {
            "type": "float"
          }
        }
      }
    }
    
    
    POST /item/_doc/
    {
    "title": "小米电视4A",
    "images": "http://image.lagou.com/12479122.jpg",
    "price": 4288
    }
    
    POST /item/_doc/
    {
    "title": "小米手机",
    "images": "http://image.lagou.com/12479122.jpg",
    "price": 2688
    }
    
    POST /item/_doc/
    {
    "title": "苹果手机",
    "images": "http://image.lagou.com/12479122.jpg",
    "price": 5699
    }
    
    2.1 匹配搜索
    • or关系

    match类型的查询,会把查询条件分词,多个词条之间是or的关系。如下面的例子,会根据小米和手机分别去搜索,能搜出3条数据。

    POST /item/_search
    {
      "query":{
        "match": {
          "title": "小米手机"
        }
      }
    }
    
    • and关系
    POST /item/_search
    {
      "query":{
        "match": {
          "title": {
            "query": "小米手机",
            "operator":"and"
          }
        }
      }
    }
    
    2.2 短语搜索

    match_phrase查询用来对一个字段进行短语查询,可以指定analyzer、slop移动因子

    POST /item/_search
    {
      "query":{
       "match_phrase": {
         "title": "小米手机"
       }
      }
    }
    

    带slop:

    POST /item/_search
    {
      "query":{
       "match_phrase": {
         "title": {
           "query": "手机小米",
           "slop":2
         }
       }
      }
    }
    

    slop参数告诉match_phrase查询词条能够相隔多远时仍然将文档视为匹配。相隔多远的意思是,你需要移动一个词条多少次来让查询和文档匹配

    2.3 query_string 查询

    query string提供了无需指定某字段而对文档全文进行匹配查询的一个高级查询,同时可以指定在哪些字段上进行匹配。

    GET /item/_search
    {
      "query": {
        "query_string": {
          "query": "2688"
        }
      }
    }
    
    GET /item/_search
    {
      "query": {
        "query_string": {
          "default_field": "price", 
          "query": "2688"
        }
      }
    }
    
    GET /item/_search
    {
      "query": {
        "query_string": {
          "default_field": "title", 
          "query": "手机 OR 小米"
        }
      }
    }
    
    GET /item/_search
    {
      "query": {
        "query_string": {
          "default_field": "title", 
          "query": "手机 and 小米"
        }
      }
    }
    
    #模糊查询
    GET /item/_search
    {
      "query": {
        "query_string": {
          "default_field": "title", 
          "query": "小米~1"
        }
      }
    }
    
    #多字段支持
    GET /item/_search
    {
      "query": {
        "query_string": {
          "fields": ["title","price"], 
          "query": "2699"
        }
      }
    }
    
    2.4 多字段匹配搜索

    如果你需要在多个字段上进行文本搜索,可用multi_match。

    GET /item/_search
    {
      "query": {
        "multi_match": {
          "query": "2688",
          "fields": ["title","price"]
        }
      }
    }
    
    #还可以使用*配置
    
    GET /item/_search
    {
      "query": {
        "multi_match": {
          "query": "2688",
          "fields": ["title","pri*"]
        }
      }
    }
    

    3. 词条搜索

    可以使用term-level queries根据结构化数据中的精确值查找文档。term-level queries不分析搜索词。搜索词与存储在字段中的词需要完全匹配

    3.1 词条普通搜索

    用于查询指定字段包含某个搜索词的文档

    POST /item/_search
    {
      "query": {
        "term": {
          "title":"小米"
        }
      }
    }
    
    3.2 词条集合搜索
    POST /item/_search
    {
      "query": {
        "terms": {
          "title": ["小米","电视"]
        }
      }
    }
    
    3.3 范围搜索
    • gte:大于等于
    • gt:大于
    • lte:小于等于
    • lt:小于
    • boost:查询权重
    POST /item/_search
    {
      "query": {
        "range": {
          "price": {
            "gte": 10,
            "lte": 3000
          }
        }
      }
    }
    
    #日期范围
    POST /item/_search
    {
      "query": {
        "range": {
          "createTime": {
            "gte": "2022-01-01",
            "lte": "2022-02-01",
            "format": "yyyy-MM-dd"
          }
        }
      }
    }
    
    3.4 不为空搜索
    GET /item/_search
    {
      "query": {
        "exists": {
          "field": "price"
        }
      }
    }
    
    3.5 词项前缀搜索
    GET /item/_search
    {
      "query": {
        "prefix": {
          "title": {
            "value": "小米"
          }
        }
      }
    }
    
    3.6 通配符搜索
    GET /item/_search
    {
      "query": {
        "wildcard": {
          "title":"小*"
        }
      }
    }
    
    3.7 正则搜索
    GET /item/_search
    {
      "query": {
        "regexp": {
          "title":"小米[a-z0-9]"
        }
      }
    }
    
    3.8 模糊搜索
    GET /item/_search
    {
      "query": {
        "fuzzy": {
          "title": "手机"
        }
      }
    }
    
    #错别字纠正
    GET /item/_search
    {
      "query": {
        "fuzzy": {
          "title": {
            "value": "大米",
            "fuzziness": 1
          }
        }
      }
    }
    
    3.9 ids搜索
    GET /item/_search
    {
      "query": {
        "ids": {
          "values": ["t76YgYEB9TD2fYkcLzha","tb6XgYEB9TD2fYkc6zhx"]
        }
      }
    }
    

    4. 复合搜索

    4.1 constant_score,用来包装另一个查询,将查询匹配的文档的评分设为一个常值
    GET /item/_search
    {
      "query": {
       "constant_score": {
         "filter": {
           "term": {
             "title": "小米"
           }
         },
         "boost": 1.2
       }
      }
    }
    
    4.2 bool query,用bool组合多个查询子句为一个查询。
    • must:必须满足
    • filter:必须满足,但执行的是filter上下文,不参与、影响评分
    • should:或
    • must_not:必须不满足,在filter上下文中执行,不参与、不影响评分
    POST /item/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "title": "小米"
              }
            }
          ], "filter": {
            "term": {
              "title": "电视"
            }
          },"must_not": [
            {
              "range": {
                "price": {
                  "gte": 4200,
                  "lte": 4300
                }
              }
            }
          ]
          ,"minimum_should_match": 0
        }
      }
    }
    

    minimum_should_match代表了最小匹配精度,如果设置为1,代表should语句中至少需要有一个条件满足。

    5. 排序

    5.1 相关性评分排序

    默认情况下,返回的结果是按照相关性进行排序的。默认排序是_score降序

    # 按照评分升序
    GET /item/_search
    {
      "query": {
        "match_all": {}
      },
      "sort":[{
        "_score":{
          "order":"asc"
        }
      }
      ]
    }
    
    
    #根据字段值排序
    GET /item/_search
    {
      "query": {
        "match_all": {}
      },
      "sort":[{
        "price":{
          "order":"asc"
        }
      }
      ]
    }
    
    #多个字段的排序
    GET /item/_search
    {
      "query": {
        "match_all": {}
      },
      "sort":[{
        "price":{
          "order":"asc"
        }
      },{
        "createTime": {
          "order":"desc"
        }
      }
      ]
    }
    

    6.分页

    size:每页显示多少条

    from:当前页起始索引

    POST /item/_search
    {
      "query": {
        "match_all": {}
      }
      ,"size": 2,
      "from": 0
    }
    

    7. 高亮

    POST /item/_search
    {
      "query": {
        "match": {
          "title": "小米"
        }
      },
      "highlight": {
        "pre_tags": "<font color='pink'>",
        "post_tags": "</font>",
        "fields": [{"title":{}}]
      }
    }
    
    • pre_tags:前置标签
    • post_tags:后置标签
    • fields:需要高亮的字段
      • title:这里声明title字段需要高亮

    8. 文档批量操作

    8.1 mget批量查询

    不同的索引

    GET /_mget
    {
      "docs":[
        {
          "_index":"item",
          "_id":"tb6XgYEB9TD2fYkc6zhx"
        },
        {
          "_index":"test-location",
          "_id":1
        }
        ]
    }
    

    相同的索引

    POST /test-location/_search
    {
      "query": {
        "ids": {
          "values": ["1","2"]
        }
      }
    }
    
    8.2 bulk批量增删改

    语法:

    POST /_bulk
    {"action": {"metadata"}}
    {"data"}
    

    示例:

    POST /_bulk
      {"delete":{"_index":"item","_id":"tb6XgYEB9TD2fYkc6zhx"}}
      {"create":{"_index":"item","_id":"1"}}
      {"title":"华为电脑","price":2333}
      {"update":{"_index":"item","_id":2}}
      {"doc":{"title":"冰箱"}}
    
    • delete:删除一个文档,删除没有请求体,只需要一个json串就行
    • create:相当于强制创建
    • index:普通的PUT操作,可以创建也可以全量替换
    • update:执行的是局部更新

    格式:每个json不能换行,相邻json必须换行

    隔离:每个操作互不影响,操作失败的行会返回其失败信息

    实际用法:bulk请求一次不要太大,否则一下积压到内存中,性能会下降。所以,一次请求几千个操作、大小在几M正好。bulk会将要处理的数据载入内存中,所以数据量是有限的,最佳的数据量不是一个确定的数据,它取决于你的硬件,你的文档大小以及复杂性,你的索引以及搜索的负载。一般建议是1000-5000个文档,大小建议是5-15MB,默认不能超过100M,可以在es的配置文件(ES的config下的elasticsearch.yml)中配置。

    http.max_content_length: 10mb

    Filter

    Elasticsearch中的所有查询都会触发相关度得分的计算。对于我们不需要相关度得分的场景,Es以过滤器的形式提供了另一种查询功能,过滤器在概念上类似于查询,但是它们有非常快的执行速度,执行速度快主要有以下两个原因:

    • 过滤器不会计算相关度的得分
    • 过滤器可以被缓存到内存中,这使得在重复的搜索查询上,比相应的查询快出许多。
    {
      "query": {
        "bool":{
          "must":{
            "match_all":{}
          },
          "filter": {
            "range": {
              "price": {
                "gte": 10,
                "lte": 20000
              }
            }
          }
        }
      }
    }
    
  • 相关阅读:
    CUDA和cudnn的环境变量设置问题
    zsh-Ubuntu更实用终端
    应用安全
    应用安全
    应用安全
    操作系统
    应用安全
    应用安全
    操作系统
    密码学
  • 原文地址:https://www.cnblogs.com/javammc/p/16399339.html
Copyright © 2020-2023  润新知