查询类型 | 解释 | 关键字 | 相当于MySQL中 |
---|---|---|---|
查询所有 | 查询出所有数据,一般测试用。 | ① match_all | select * |
全文检索(full text)查询 | 利用分词器对用户输入内容分词,然后去倒排索引库中匹配。 | ①match_query;② multi_match_query | 模糊查询 |
精确查询 | 根据精确词条值查找数据,一般查找keyword、数值、日期、boolean等类型字段 | ① ids;② range;③ term | – |
地理(geo)查询 | 根据经纬度查询 | ① geo_distance;② geo_bounding_box | – |
复合(compound)查询 | 将上述各种查询条件组合起来,合并查询条件。 | ① bool;② function_score | – |
DSL语法:
GET /indexName/_search
{
"query": {
"查询类型": {
"查询条件": "条件值"
}
}
}
// 查询所有
GET /indexName/_search
{
"query": {
"match_all": {
}
}
}
属性 | 解释 | 备注 |
---|---|---|
match | 单字段查询 | 根据一个字段查询 |
multi_match | 多字段查询,任意一个字段符合条件,只要查到就给你返回 | 根据多个字段查询,参与查询字段越多,查询性能越差,建议使用all字段,copy_to方法优化 |
match查询语法:
GET /indexName/_search
{
"query": {
"match": {
"FIELD": "TEXT"
}
}
}
mulit_match语法:
GET /indexName/_search
{
"query": {
"multi_match": {
"query": "TEXT",
"fields": ["FIELD1", " FIELD12"]
}
}
}
注意:我们发现上述match、multi_match查询到的结果相同,因为:在Elasticsearch+Kibana·入门·壹中创建索引库时,我们使用到组合字段
all
,已经将brand、name、business值利用copy_to复制到all字段中,因此会出现查询结果相同。
在实际开发者,当查询多个字段时使用copy_to方法,可以减少搜索字段,相较可以提高查询性能。
精准查询一般查找keyword、数值、日期类型字段,所以
不会对搜索条件分词
。
属性 | 解释 |
---|---|
term | 根据词条精确值查询 |
range | 根据值的范围查询 |
语法:
// term查询
GET /indexName/_search
{
"query": {
"term": {
"FIELD": {
"value": "VALUE"
}
}
}
}
语法:
// range查询
GET /indexName/_search
{
"query": {
"range": {
"FIELD": {
"gte": 10, // 这里的gte代表大于等于,gt则代表大于
"lte": 20 // lte代表小于等于,lt则代表小于
}
}
}
}
官方参阅文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/geo-queries.html
应用场景:例如查找附近的酒店等。
语法:
// geo_bounding_box查询
GET /indexName/_search
{
"query": {
"geo_bounding_box": {
"FIELD": {
"top_left": { // 左上点
"lat": 31.1,
"lon": 121.5
},
"bottom_right": { // 右下点
"lat": 30.9,
"lon": 121.7
}
}
}
}
}
语法:
// geo_distance 查询
GET /indexName/_search
{
"query": {
"geo_distance": {
"distance": "15km", // 半径
"FIELD": "31.21,121.5" // 圆心
}
}
}
复合(compound)查询:将简单查询组合起来,实现复杂的搜索逻辑。
属性 | 解释 |
---|---|
fuction score | 算分函数查询,通过控制文档相关性算分(权重),控制文档排名 |
bool query | 布尔查询,利用逻辑关系组合多个查询其他查询,实现复杂搜索 |
在elasticsearch中,早期使用的打分算法是TF-IDF算法,公式如下:
注意:TF-IDF算法的
缺陷
,词条频率越高,文档得分(score)越高,词条出现次数对文档影响较大。而BM25则会使单个词条的算分出现上限,分子(词条出现次数过多)趋向于文档中词条总数时,曲线会变平滑,此时相关性算分幅度基本保持不变,使得控制文档排名业务复杂。
算分函数内容 | 解释 |
---|---|
原始查询 | 查询方式可根据需求改变,如:查询品牌中出现万怡字眼的,并中根据下方过滤,得到最终负荷调节的将要设置算分的文档,并得到默认原始算分文档 |
过滤条件 | 查询方式可根据需求改变,得到最终符合条件的将要设置算分文档 |
算分函数 | 与下方boost_mode相结合,再依据原始算分,得到最终算分结果 |
运算模式 | 也就是加权模式,multiply与weight相乘(默认方式) |
① 根据原始条件查询文档,得到
原始算分
② 根据过滤条件,过滤文档
③ 得到符合过滤条件的文档,设置权重
,得到函数算分
④ 将此处的加权模式
与上方函数算分
做出计算
,得到最终相关性算分
。
#将上海地区的如家品牌酒店排名靠前
GET /hotel/_search
{
"query": {
"function_score":{
"query": {
"match": {
"all": "上海"
}
},
"functions": [
{
"filter": {
"term": {
"brand": "如家"
}
},
"weight": 100
}
],
"boost_mode": "multiply"
}
}
}
布尔查询(bool):查询时,在
bool方法体内
,使用一个或多个支持下的组合,每一个字句就是一个子查询,子查询的组合方式:
条件 | 解释 |
---|---|
must | 必须匹配每个子查询,类似“与” |
should | 选择性匹配子查询,类似“或” |
must_not | 必须不匹配,不参与算分,类似“非” |
filter | 必须匹配,不参与算分 |
注意:打分的字段越多,查询的性能也越差。优化方法:
- ①当全文检索时,使用must查询,参与算分
- ②其他过滤条件,采用filter查询,不参与算分
GET /hotel/_search
{
"query": {
"bool": {
"must": [
{"term": {"city": "上海" }}
],
"should": [
{"term": {"brand": "皇冠假日" }},
{"term": {"brand": "华美达" }}
],
"must_not": [
{ "range": { "price": { "lte": 500 } }}
],
"filter": [
{ "range": {"score": { "gte": 45 } }}
]
}
}
}
需求:搜索名字包含“如家”,价格不高于400,在坐标31.21,121.5周围10km范围内的酒店。
#搜索名字包含“如家”,价格不高于400,在坐标31.21,121.5周围10km范围内的酒店
GET /hotel/_search
{
"query": {
"bool": {
"must": [
{
"match": {//模糊查询,匹配名字中含有如家关键字的酒店吗
"name": "如家"
}
}
],
"must_not": [
{
"range": {//子查询
"price": {
"gt": 400 //非大于400,即小于400的价格
}
}
}
],
"filter": [ //过滤子查询,得到位置信息内的相关酒店
{
"geo_distance": {
"distance": "10km",
"location": {
"lat": 31.21,
"lon": 121.5
}
}
}
]
}
}
}