美文网首页
12.elasticsearch使用

12.elasticsearch使用

作者: 星野君 | 来源:发表于2022-05-23 16:34 被阅读0次

    mapping常见属性有哪些?

    • type:数据类型
    • index:是否索引
    • analyzer:分词器
    • properties:子字段
      type常见的有哪些?
    • 字符串:text、keyword
    • 数字:long、integer、short、byte、double、float
    • 布尔:boolean
    • 日期:date
    • 对象:object

    索引库

    # 创建索引库
    PUT /user
    {
      "mappings": {
        "properties": {
          "name": {
            "type": "object",
            "properties": {
              "firstName": {
                "type": "keyword"
              },
              "lastName": {
                "type": "keyword"
              }
            }
          },
          "info": {
            "type": "text",
            "analyzer": "ik_smart"
          },
          "email": {
            "type": "keyword",
            "index": false
          }
        }
      }
    }
    
    
    # 查看索引库
    GET /user
    
    #删除索引库
    DELETE /user
    
    #修改/添加新字段
    PUT /user/_mapping
    {
      "properties":{
        "age":{
          "type":"integer"
        }
      }
    }
    

    文档

    #插入文档
    POST /user/_doc/1
    {
      "age":15,
      "email":"775225123@qq.com",
      "info":"大家好才是真的好,广州好滴",
      "name":{
        "firstName":"张",
        "lastName":"三"
      }
    }
    
    #查询文档
    GET /user/_doc/1
    
    #删除文档
    DELETE /user/_doc/1
    
    #全量修改,先删除后新增,id存在即修改不存在即新增
    PUT /user/_doc/1
    {
      "age":18,
      "email":"775225123@qq.com",
      "info":"大家好才是真的好,广州好滴",
      "name":{
        "firstName":"三",
        "lastName":"张"
      }
    }
    
    #增量修改,修改指定字段
    POST /user/_update/1
    {
      "doc": {
        "age":16
      }
    }
    

    DSL查询语句

    全文检索查询

    1. 查询所有
    GET /hotel/_search
    {
      "query": {
        "match_all": {}
      }
    }
    
    1. match查询:全文检索查询的一种,会对用户输入内容分词,然后去倒排索引库检索,语法:
    GET /hotel/_search
    {
      "query": {
        "match": {
          "all": "外滩"
        }
      }
    }
    
    1. multi_match:与match查询类似,只不过允许同时查询多个字段,语法:
    # multi_match查询
    GET /hotel/_search
    {
      "query": {
        "multi_match": {
          "query": "外滩如家",
          "fields": ["brand","name","business"]
        }
      }
    }
    

    match和multi_match的区别是什么?

    • match:根据一个字段查询
    • multi_match:根据多个字段查询,参与查询字段越多,查询性能越差,建议使用copy_to加到一个字段里去查
    PUT my_index
    {
      "mappings": {
        "properties": {
          "first_name": {
            "type": "text",
            "copy_to": "full_name" 
          },
          "last_name": {
            "type": "text",
            "copy_to": "full_name" 
          },
          "full_name": {
            "type": "text"
          }
        }
      }
    }
    

    精确查询
    精确查询一般是查找keyword、数值、日期、boolean等类型字段。所以不会对搜索条件分词。常见的有:

    1. term:根据词条精确值查询
    #term查询
    GET /hotel/_search
    {
      "query": {
        "term": {
          "brand": {
            "value": "如家"
          }
        }
      }
    }
    
    1. range:根据值的范围查询
    #range查询
    GET /hotel/_search
    {
      "query": {
        "range": {
          "price": {
            "gte": 100,
            "lte": 200
          }
        }
      }
    }
    

    地理查询

    1. geo_distance:查询到指定中心点小于某个距离值的所有文档
    #geo_distance查询
    GET /hotel/_search
    {
      "query": {
        "geo_distance":{
          "distance":"15km",
          "location":"31.047135, 121.46224"
        }
      }
    }
    
    1. geo_bounding_box:查询geo_point值落在某个矩形范围的所有文档
    #geo_bounding_box查询
    GET /hotel/_search
    {
      "query": {
        "geo_bounding_box": {
          "location": {
            "top_left": {
              "lat": "31.1",
              "lon": "121.5"
            },
            "bottom_right": {
              "lat": "30.9",
              "lon": "121.7"
            }
          }
        }
      }
    }
    

    复合查询
    复合(compound)查询:复合查询可以将其它简单查询组合起来,实现更复杂的搜索逻辑,例如:

    1. function_score:算分函数查询,可以控制文档相关性算分,控制文档排名。例如百度竞价
    #fuction score查询
    GET /hotel/_search
    {
      "query": {
        "function_score": {
          "query": {
            "match": {
              "all": "外滩"
            }
          },
          "functions": [
            {
              "filter": {
                "term": {
                  "brand": "如家"
                }
              },
              "weight": 10
            }
          ]
          , "boost_mode": "sum"
        }
      }
    }
    
    • query:原始查询条件,搜索文档并根据相关性打分(q
    • filter:过滤条件,符合条件的文档才会被重新算分
    • weight:算分函数,算分函数的结果称为function score ,将来会与query score运算,得到新算分,常见的算分函数有:
      • weight:给一个常量值,作为函数结果(function score)
      • field_value_factor:用文档中的某个字段值作为函数结果
      • random_score:随机生成一个值,作为函数结果
      • script_score:自定义计算公式,公式结果作为函数结果
    • boost_mode:加权模式,定义function score与query score的运算方式,包括
      • multiply:两者相乘。默认就是这个
      • replace:用function score 替换 query score
      • 其它:sum、avg、max、min
    1. 复合查询 Boolean Query
      布尔查询是一个或多个查询子句的组合。子查询的组合方式有:
    • must:必须匹配每个子查询,类似“与”
    • should:选择性匹配子查询,类似“或”
    • must_not:必须不匹配,不参与算分,类似“非”
    • filter:必须匹配,不参与算分
    #Boolean Query查询
    GET /hotel/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "name": "上海"
              }
            }
          ],
          "should": [
            {
              "term": {
                "brand": {
                  "value": "华美达"
                }
              }
            },
            {
              "term": {
                "brand": {
                  "value": "如家"
                }
              }
            }
          ],
          "must_not": [
            {
              "range": {
                "price": {
                  "lte": 100
                }
              }
            }
          ],
          "filter": [
            {
              "geo_distance": {
                "distance": "15km",
                "location": {
                  "lat": 31.2,
                  "lon": 121.4
                }
              }
            }
          ]
        }
      }
    }
    

    查询名称包括上海,品牌为如家或者华美达,价格大于100,经纬度31.2,121.4附件14km的酒店

    搜索结果处理

    排序
    elasticsearch支持对搜索结果排序,默认是根据相关度算分(_score)来排序。可以排序字段类型有:keyword类型、数值类型、地理坐标类型、日期类型等。

    #简单字段排序
    GET /hotel/_search
    {
      "query": {
        "match_all": {}
      },
      "sort": [
        {"score": "desc"},
        {"price": "desc"}
      ]
    }
    
    #地理位置排序
    GET /hotel/_search
    {
      "query": {
        "match_all": {}
      },
      "sort": [
        {
          "_geo_distance": {
            "location": "28.68925,115.874233",
            "order": "asc",
            "unit": "km"
          }
        }
      ]
    }
    

    分页

    #分页
    GET /hotel/_search
    {
      "query": {
        "match_all": {}
      },
      "from": 0,
      "size": 2
    }
    
    • from + size:
      • 优点:支持随机翻页
      • 缺点:深度分页问题,默认查询上限(from + size)是10000
      • 场景:百度、京东、谷歌、淘宝这样的随机翻页搜索
        -after search:
      • 优点:没有查询上限(单次查询的size不超过10000)
      • 缺点:只能向后逐页查询,不支持随机翻页
      • 场景:没有随机翻页需求的搜索,例如手机向下滚动翻页

    高亮

    #高亮
    GET /hotel/_search
    {
      "query": {
        "match": {
          "all": "如家"
        }
      },
      "highlight": {
        "fields": {
          "name": {
            "require_field_match": "false"
          }
        }
      }
    }
    

    默认情况下,搜索的关键字必须和高亮的字段保持一致,如果非要高亮不一样的字段,就加上"require_field_match": "false"

    聚合

    聚合的分类
    聚合(aggregations)可以实现对文档数据的统计、分析、运算。聚合常见的有三类:

    • 桶(Bucket)聚合:用来对文档做分组
      • TermAggregation:按照文档字段值分组
      • Date Histogram:按照日期阶梯分组,例如一周为一组,或者一月为一组
    • 度量(Metric)聚合:用以计算一些值,比如:最大值、最小值、平均值等
      • Avg:求平均值
      • Max:求最大值
      • Min:求最小值
      • Stats:同时求max、min、avg、sum等
    • 管道(pipeline)聚合:其它聚合的结果为基础做聚合

    Bucket聚合

    #聚合功能
    GET /hotel/_search
    {
      "size": 0,
      "aggs": {
        "brandAgg": {
          "terms": {
            "field": "brand",
            "size": 20
          }
        }
      }
    }
    

    限定聚合范围

    #聚合功能,限定范围
    GET /hotel/_search
    {
      "query": {
        "range": {
          "price": {
            "gte": 100,
            "lte": 200
          }
        }
      }, 
      "size": 0,
      "aggs": {
        "brandAgg": {
          "terms": {
            "field": "brand",
            "size": 20
          }
        }
      }
    }
    

    Metrics 聚合
    获取每个品牌的用户评分的min、max、avg

    #Metrics 聚合求酒店评分,并排序
    GET /hotel/_search
    {
      "size": 0,
      "aggs": {
        "brandAgg": {
          "terms": {
            "field": "brand",
            "size": 20,
            "order": {
              "scoreAgg.avg": "desc"
            }
          },"aggs": {
            "scoreAgg": {
              "stats": {
                "field": "score"
              }
            }
          }
        }
      }
    }
    

    拼音分词器

    GET /_analyze
    {
      "text": ["如家酒店还不错"],
      "analyzer": "pinyin"
    }
    
    1. 自定义分词器
      elasticsearch中分词器(analyzer)的组成包含三部分:
    • character filters:在tokenizer之前对文本进行处理。例如删除字符、替换字符
    • tokenizer:将文本按照一定的规则切割成词条(term)。例如keyword,就是不分词;还有ik_smart
    • tokenizer filter:将tokenizer输出的词条做进一步处理。例如大小写转换、同义词处理、拼音处理等

    我们可以在创建索引库时,通过settings来配置自定义的analyzer(分词器)

    # 自定义拼音分词器
    PUT /test
    {
      "settings": {
        "analysis": {
          "analyzer": { 
            "my_analyzer": { 
              "tokenizer": "ik_max_word",
              "filter": "py"
            }
          },
          "filter": {
            "py": { 
              "type": "pinyin",
              "keep_full_pinyin": false,
              "keep_joined_full_pinyin": true,
              "keep_original": true,
              "limit_first_letter_length": 16,
              "remove_duplicated_term": true,
              "none_chinese_pinyin_tokenize": false
            }
          }
        }
      },"mappings": {
        "properties": {
          "name":{
            "type": "text",
            "analyzer": "my_analyzer",
            "search_analyzer": "ik_smart"
          }
        }
      }
    }
    

    自动补全

    #自动补全的索引库
    PUT test2
    {
      "mappings": {
        "properties": {
          "title":{
            "type": "completion"
          }
        }
      }
    }
    #示例数据
    POST test2/_doc
    {
      "title": ["Sony", "WH-1000XM3"]
    }
    POST test/_doc
    {
      "title": ["SK-II", "PITERA"]
    }
    POST test/_doc
    {
      "title": ["Nintendo", "switch"]
    }
    
    // 自动补全查询
    POST /test/_search
    {
      "suggest": {
        "title_suggest": {
          "text": "s", // 关键字
          "completion": {
            "field": "title", // 补全字段
            "skip_duplicates": true, // 跳过重复的
            "size": 10 // 获取前10条结果
          }
        }
      }
    }
    

    相关文章

      网友评论

          本文标题:12.elasticsearch使用

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