DSL查询语法
Elasticsearch提供了基于JSON的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
查询的基本语法
GET /indexName/_search
{
"query": {
"查询类型": {
"查询条件": "条件值"
}
}
}
1.查询所有
GET /hotel/_search
{
"query": {
"match_all": {
}
}
}
分页查询
GET /hotel/_search
{
"query": {
"match_all": {}
},
"from": 0,
"size": 5
}
_score:[“字段名”,"字段名”]:只返回该字段的数据
GET /hotel/_search
{
"query": {
"match_all": {}
},
"from": 0,
"size": 5,
"_source": ["address","price"]
}
2.全文检索查询
match查询:全文检索的一种,会对用户输入内容分词,然后去倒排索引库检索
GET /hotel/_search
{
"query": {
"match": {
"all":"如家"
}
}
}
multi_match:与match查询类似,只不过允许同时查询多个字段
GET /hotel/_search
{
"query": {
"multi_match": {
"query":"如家",
"fields": ["brand","name","business"]
}
}
}
只要brand,name,business中含有“如家”就能被检索出来
但是根据多个字段查询性能较差,建议使用copy_to将要查询的字段拷贝到一个字段all中,然后使用match查询
match_phrase:短语品牌
GET /hotel/_search
{
"query": {
"match_phrase": {
"brand": "7天酒店"
}
}
}
不将字段中的内容进行分词,直接看做一个短语处理
3.精确查询
term:根据词条精确值查询
GET /hotel/_search
{
"query": {
"term": {
"city": {
"value": "上海"
}
}
}
}
range:根据值的范围查询
GET /hotel/_search
{
"query": {
"range": {
"price": {
"gte": 100,
"lte": 200
}
}
}
“gte"是大于等于
"gt"是大于
"lte"是小于等于
"lt"是小于
4.地理查询
根据经纬度查询
geo_bounding_box:查询geo_point值落在某个矩形范围内
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":"15km",
"location":"31.21,121.5"
}
}
}
5.复合查询
function score 查询
当我们利用match查询时,文档结果会根据与搜索词条的关联连度打分,返回结果按照分值降序排列
TF-IDF:在elasticsearch5.0之前,会随着词频增大而越来越大
BM25:在elasticsearch5.0之后,会随着词频增大而增大,但增长曲线会趋于水平
算分函数
使用funcation score query 可以修改文档的相关性算分,根据新得到的算分排序
function score 查询中包含四部分内容:
1、原始查询条件:query部分,基于这个条件搜索文档,并且基于BM25算法给文档打分,原始算分(query score)
2、过滤条件:filter部分,符合该条件的文档才会重新算分
3、算分函数:符合filter条件的文档要根据这个函数做运算,得到的函数算分(function score),有四种函数
weight:函数结果是常量
field_value_factor:以文档中的某个字段值作为函数结果
random_score:以随机数作为函数结果
script_score:自定义算分函数算法
4、运算模式:算分函数的结果、原始查询的相关性算分,两者之间的运算方式,包括:
multiply:相乘 (默认)
replace:用function score替换query score
其它,例如:sum、avg、max、min
function score的运行流程如下:
-
根据原始条件查询搜索文档,并且计算相关性算分,称为原始算分(query score)
-
根据过滤条件,过滤文档
-
符合过滤条件的文档,基于算分函数运算,得到函数算分(function score)
-
将原始算分(query score)和函数算分(function score)基于运算模式做运算,得到最终结果,作为相关性算分。
注:
过滤条件:哪些文档要加分
算分函数:决定函数算分的算法
运算模式:决定最终算分结果
举例:
给在外滩且品牌名为如家的加分
GET /hotel/_search
{
"query": {
"function_score": {
"query": {
"match": {
"all": "外滩"
}
},
"functions": [
{
"filter": {
"term": {
"brand": "如家"
}
},
"weight": 10
}
]
}
}
}
布尔查询
布尔查询是一个或多个查询字句的组合。子查询的组合方式有:
-
must:必须匹配每个子查询,类似“与”
-
should:选择性匹配子查询,类似“或”
-
must_not:必须不匹配,不参与算分,类似“非”
-
filter:必须匹配,不参与算分
案例:搜索名字包含”如家“,价格不高于400,在坐标31.21,121.5周围10km范围内的酒店
GET /hotel/_search
{
"query": {
"bool":{
"must": [
{
"match": {
"name": "如家"
}
}
],
"must_not": [
{
"range": {
"price": {
"gt": 400
}
}
}
],
"filter": [
{
"geo_distance": {
"distance": "10km",
"location": {
"lat": 31.21,
"lon": 121.5
}
}
}
]
}
}
}