ES-DSL查询文档&搜索结果处理

DSL查询文档

  • 查询所有:查询出所有数据,一般测试用。例如:match_all
  • 全文检索(full text)查询:利用分词器对用户输入内容分词,然后去倒排索引库中匹配。例如:

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

    • ids
    • range
    • term
  • 地理(geo)查询:根据经纬度查询。例如:

    • geo_distance
    • geo_bounding_box
  • 复合(compound)查询:复合查询可以将上述各种查询条件组合起来,合并查询条件。例如:

    • bool
    • function_score

1.全文检索查询

#match查询    //搜索字段越多,对查询性能影响越大,因此建议采用copy_to,然后单字段查询的方式比较好
GET /hotel/_search
{
  "query": {
    "match": {
      "all":"上海外滩"
    }
  }
}
#multi_match查询
GET /hotel/_search
{
  "query": {
    "multi_match": {
      "query": "如家",
      "fields": ["name","business"]
    }
  }
}

2.精准查询

2.1term查询

因为精确查询的字段搜是不分词的字段,因此查询的条件也必须是不分词的词条。查询时,用户输入的内容跟自动值完全匹配时才认为符合条件。如果用户输入的内容过多,反而搜索不到数据。

//term 精准查询
GET /hotel/_search
{
  "query": {
    "term": {
      "name": {
        "value": "上海"
      }
    }
  }
}

2.22.range查询

范围查询,一般应用在对数值类型做范围过滤的时候。比如做价格范围过滤

//range 范围查询
GET /hotel/_search
{
  "query": {
    "range": {
      "price": {
        "gte": 100,
        "lte": 200
      }
    }
  }
}

3.地理坐标查询

所谓的地理坐标查询,其实就是根据经纬度查询

官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/geo-queries.html

常见的使用场景包括:

  • 携程:搜索我附近的酒店
  • 滴滴:搜索我附近的出租车
  • 微信:搜索我附近的人
#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
        }
      }
    }
  }
}
#geo_distance 距离查询
GET /hotel/_search
{
  "query": {
    "geo_distance":{
      "distance":"100km",
      "location":"39.909187,116.397455" //天安门
    }
  }
}

4.算分函数查询

function score 查询中包含四部分内容:

  • 原始查询条件:query部分,基于这个条件搜索文档,并且基于BM25算法给文档打分,原始算分(query score)
  • 过滤条件:filter部分,符合该条件的文档才会重新算分
  • 算分函数:符合filter条件的文档要根据这个函数做运算,得到的函数算分(function score),有四种函数

    • weight:函数结果是常量
    • field_value_factor:以文档中的某个字段值作为函数结果
    • random_score:以随机数作为函数结果
    • script_score:自定义算分函数算法
  • 运算模式:算分函数的结果、原始查询的相关性算分,两者之间的运算方式,包括:

    • multiply:相乘
    • replace:用function score替换query score
    • 其它,例如:sum、avg、max、min
#算分查询
GET /hotel/_search
{
  "query": {
    "function_score": {
      "query": {
        "match": {
          "all": "外滩"
        }
      },
      "functions": [
        {
          "filter": {
            "term": {
              "brand": "如家"
            }
          },
          "weight": 10   //加权重
        }
      ],
      "boost_mode": "sum"
    }
  }
}

5.布尔查询

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

  • must:必须匹配每个子查询,类似“与”
  • should:选择性匹配子查询,类似“或”
  • must_not:必须不匹配,不参与算分,类似“非”
  • filter:必须匹配,不参与算分

示例

需求:搜索名字包含“如家”,价格不高于400,在坐标39.909187,116.397455周围10km范围内的酒店。

分析:

  • 名称搜索,属于全文检索查询,应该参与算分。放到must中
  • 价格不高于400,用range查询,属于过滤条件,不参与算分。放到must_not中
  • 周围10km范围内,用geo_distance查询,属于过滤条件,不参与算分。放到filter中
#布尔查询
GET /hotel/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "multi_match": {
            "query": "如家",
            "fields": [
              "name"
            ]
          }
        }
      ],
      "must_not": [
        {
          "range": {
            "price": {
              "gte": 0,
              "lte": 400
            }
          }
        }
      ],
      "filter": [
        {
          "geo_distance": {
            "distance": "10km",
            "location": "39.909187,116.397455"
          }
        }
      ]
    }
  }
}

搜索结果操作

搜索结果

排序sort

GET /hotel/_search
{
"query": {

"match_all": {
  
}

},
"sort": [

{
  "price": {
    "order": "desc"
  }
}

]
}

地理坐标排序

GET /hotel/_search
{
"query": {

"match_all": {}

},
"sort": [

{
  "_geo_distance": {
    "order": "desc",
    "location": {
      "lat": 31.208553,
      "lon": 121.518552
    },
    "unit": "km"
  }
}

]
}

分页排序

GET /hotel/_search
{
"query": {

"match_all": {}

},
"from": 0,
"size": 5,
"sort": [

{
  "price": {
    "order": "desc"
  }
}

]
}

高亮

如果要对非搜索字段高亮,则需要添加一个属性:required_field_match=false

GET /hotel/_search
{
"query": {

"match": {
  "all": "如家"
}

},
"highlight": {

"fields": {
  "name": {
    "require_field_match": "false"  
  }
}

}
}

// 查询条件,高亮一定要使用全文检索查询

GET /hotel/_search
{
"query": {

"match": {
  "brand": "如家"
}

},
"highlight": {

"fields": {
  "brand": {
    "pre_tags": "<em>",
    "post_tags": "</em>"
  }
}

}
}

打赏
评论区
头像
    头像

    感谢分享

本网站由提供CDN加速/云存储服务