6.1 DSL查询文档

一、DSL查询分类

  1. DSL Query的分类

    ES提供了基于JSON的DSLDomain Specific Language来定义查询,常见的查询类型包括:

    1. 查询所有:查询出所有的数据,一般测试用。例如:match_all

    2. 全文检索(full text)查询:利用分词器对用户输入内容分词,然后去倒排索引库中匹配。例如:

      • match_query

      • Multi_match_query

    3. 精确查询:根据精确词条值查找数据,一般是查找keyword、数值、日期、boolean等类型字段。例如:

      • ids id值

      • range 数值范文做查询

      • term 精确的数值查询

    4. 地理(geo)查询:根据经纬度查询。例如:

      • geo_distance

      • geo_bounding_box

    5. 复合(compound)查询:复合查询可以将上面的查询条件组合起来,合并查询条件。例如:

      1. bool 逻辑运算(与、或、非)拼接查询

      2. function_score

  2. 查询的基本语法

    GET /索引库名/_search
    {
        "query": {
            "查询类型": {
                "查询条件": "条件值"
            }
        }
    }

    查询所有

    GET /索引库名/_search
    {
        "query": {
            "match_all": {
            }
        }
    }

二、全文检索查询

  1. 全文检索查询,会对用户输入内容分词,然后再去查询,常用于搜索框搜索:

    1. match查询:全文检索查询的一种,会对用户输入内容分词,然后去倒排索引库检索,语法:

      GET /索引库名称/_search
      {
          "query": {
              "match": {
                  "字段名": "内容"
              }
          }
      }

      备注:原来创建的时候新建了all字段,并拷贝了很多内容,因此可以直接使用all字段去查就行

    2. multi_match查询:与match查询类似,只不过允许同时查询多个字段,语法:

      GET /索引库名称/_search
      {
          "query": {
              "multi_match": {
                  "query": "内容",
                  "fields": ["字段名", "字段名2"...]
              }
          }
      }

三、精准查询

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

    1. term:根据词条精确查询

      GET /索引库名称/_search
      {
          "query": {
              "term": {
                  "字段名": {
                      "value": "具体值"
                  }
              }
          }
      }
    2. range:根据值的范围查询

      GET /索引库名称/_search
      {
          "query": {
              "range": {
                  "字段名": {
                      "gte": "最小值",
                      "lte": "最大值"
                  }
              }
          }
      }

      备注:gte:大于等于 ge:大于

      ​ lte:小于等于 lt:小于

四、地理坐标查询

  1. 根据经纬度查询。常见的使用场景包括:

    1. geo_bounding_box:查询geo_point值落在某个矩形范围的所有文档

      GET /索引库名称/_search
      {
          "query": {
              "geo_bounding_box": {
                  "文档中地理坐标的字段": {
                      "top_left": {
                          "lat": 值,
                          "lon": 值
                      },
                      "bottom_right": {
                          "lat": 值,
                          "lon": 值
                      }
                  }
              }
          }
      }
    2. geo_distance:查询到制定中心点小于某个距离的所有文档

      GET /索引库名称/_search
      {
          "query": {
              "geo_distance": {
                  "distance": "距离+单位,如15KM",
                  "文档中地理坐标的字段": "中心点坐标"
              }
          }
      }

五、组合查询

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

    1. function score:算分函数查询,可以控制文档相关性算分,控制文档排名。例如百度竞价

      GET /索引库名称/_search
      {
          "query": {
              "function_score": {
                  "query": {    // 原始查询条件(query score)
                      "match": {
                          "字段名": "条件值"
                      }
                  }
              }
          },
          "function": [
              {
                  "filter": {   // 过滤条件,复合条件的文档才会被重新算分
                      "term": {
                          "字段名": "条件值"
                      }
                  },
                  "算分函数": 值  //算分函数(function score) 
              }
          ],
          "boost_mode": "multiply"  // 加权模式,定义function score与query score
      }

      备注:常见的算分函数如下:

      ​ weight:给一个常量值,作为函数的结果

      ​ field_value_factor:用文档中的某个字段值作为函数结果

      ​ random_score:随机生成一个值,作为函数的结果

      ​ script_score:自定义计算公式,公式结果作为函数结果

      ​ 常见加权模式如下:

      ​ multiply:两者相乘,默认为它

      ​ replace:function score替换query score

      ​ 其他:sum、avg、max、min

    2. Boolean Query

      布尔查询是一个或多个查询字句的组合。子查询的组合方式有:

      1. must:必须匹配每个子查询,类似“与”

      2. should:选择性匹配子查询,类似“或”

      3. must_not:必须不匹配,不参与算分,类似“非”

      4. filter:必须匹配,不参与算分

      GET /索引库名称/_search
      {
          "query": {
              "bool": {
                  "must": [
                      {"term": {"字段名": "条件值"}}
                  ],
                  "should": [
                      {"term": {"字段名": "条件值"}},
                      {"term": {"字段名": "条件值"}}
                  ],
                  "must_not": [
                      {"range": {"字段名": {"lte": 500}}}  // lte是条件,详情看上面
                  ],
                  "filter": [
                  	{"range": {"字段名": {"get": 45}}} // get是条件,详情看上面
                  ]
              }
          }
      }
  2. 相关性打分算法:

    使用match查询时,文档结果会根据与搜索词条的关联度打分(_score),返回结果时按照分值降序排列

    TF算法

    TF(词条频率)=词条出现次数文档中词条总数TF(词条频率) = {词条出现次数 \over 文档中词条总数}

    TF-IDF算法

    IDF(逆文档频率)=Log(文档总数包含词条的文档总数)score=ΣinTF(词条频率)IDF(逆文档频率)IDF(逆文档频率) = Log({文档总数 \over 包含词条的文档总数}) \\ score = \Sigma_i^nTF(词条频率) * IDF(逆文档频率)

    BM25算法

    Score(Q,d)=ΣinLog(1+Nn+0.5n+0.5)fifi+ki(1b+bdlavgdl)Score(Q,d) = \Sigma_i^n Log(1+{N-n+0.5 \over n+0.5})\cdot {f_i \over f_i+k_i \cdot (1-b+b\cdot{dl \over avgdl})}

最后更新于

这有帮助吗?