ES dsl搜索
QueryString的方式查询数据
名称 | 值 | 备注 |
---|---|---|
请求方式 | GET | |
请求地址 | http://192.168.3.214:9200/index/_search?q=desc:你好 | |
解析 | index | 索引名称 |
_search | 表示搜索 | |
q=desc:你好 | 表示查询desc这个字段里面包含你好的数据 |
多个查询条件可以在q后面再加一个q=age:22. 例如:?q=desc:你好&q=age:22
DSL的方式查询数据
QueryString的方式查询数据不够灵活,不适用复杂查询。 使用DSL的方式查询更加灵活、方便、支持复杂查询。
使用DSL查询数据方法
名称 | 值 | 备注 |
---|---|---|
请求方式 | POST | |
请求地址 | http://192.168.3.214:9200/index/_doc/_search | |
参数类型 | JSON | 参数格式见下表 |
根据字段内容查询数据
根据字段查询数据,如果该字段不支持分词,例如keyword类型的字段,查询的字段内容只是一部分的话,是查不出来数据的。
{
"query": {
"match": {
"desc": "你好"
}
}
}
如果要查询同时满足两个词汇都存在的数据,可以使用下面这种方式查询:
{
"query": {
"match": {
"desc": {
"query": "你好 学习",
"operator":"and" # 表示要同时满足查询的所有词汇,默认是or,相当于上面的方式查询
}
}
}
}
minimum_should_match, 这个属性表示查询的字符串被分词后,匹配百分之多少词汇的数据。例如查询:今天天气好晴朗,我想出去玩。假设这个句子被分成10个词汇,minimum_should_match参数设置60%(向下取整 ),表示查询的数据中,匹配上6个词汇就会被查询出来。
{
"query": {
"match": {
"desc": {
"query": "今天天气好晴朗,我想出去玩",
"minimum_should_match": "60%"
}
}
}
}
查询索引是否包含某个属性
{
"query": {
"exists": {
"field": "username"
}
}
}
查询所有
{
"query": {
"match_all": {}
}
}
查询部分字段数据
{
"query": {
"match_all": {}
},
"_source": [
"id",
"nickname",
"age"
]
}
分页查询
{
"query": {
"match_all": {}
},
"_source": [
"id",
"nickname",
"age"
],
"from": 0, # 数据起始位置
"size": 10 # 每页展示数量
}
根据字段内容模糊匹配
{
"query": {
"term": {
"desc": "你好"
}
},
"_source": [
"id",
"nickname",
"desc"
]
}
term 是模糊搜索这个字段内容,只要这个字段内容包含搜索的字符串,就展示出来,match是分词搜索,首先会对搜索的字符串进行分词,然后会检索出所有包含这些分词的数据。
也可以同时查询多个词汇:
{
"query": {
"terms": {
"desc": ["你好", "学习"]
}
},
"_source": [
"id",
"nickname",
"desc"
]
}
使用terms是可以支持多个词汇查询,只要包含搜索词汇中的其中一个,就会被检索出来。
根据词条去查询
{
"query": {
"match_phrase": {
"desc": {
"query": "大学 毕业"
}
}
},
"_source": [
"id",
"nickname",
"desc"
]
}
使用match_phrase查询,首先会对查询的词条进行分词,然后去找这些分词同时在这个字段内容下的数据。上面的例子两个词汇,需要连贯在一起才能查询出来。如果要查询非连贯的词汇,可以使用下面的方式。
{
"query": {
"match_phrase": {
"desc": {
"query": "大学 毕业",
"slop": 3 # 这个参数表示大学和毕业中间可以跳过多少个词汇
}
}
},
"_source": [
"id",
"nickname",
"desc"
]
}
指定多个ID查询
{
"query": {
"ids": {
"type": "_doc",
"values": ["1001", "1002", "1009"]
}
},
"_source": [
"id",
"nickname",
"desc"
]
}
在多个字段去查询
{
"query": {
"multi_match": {
"desc": "你好啊",
"fields": [
"desc", "nickname^10"
]
}
}
}
由于默认匹配的词汇越少,分数越低,搜索出来的数据排名会靠下,如果要对某个字段查询出来的数据提升排名,则可以为这个字段设置权重,设置方法见上方:"nickname ^ 10"
布尔查询
{
"query": {
"bool": {
"must": [
{
"multi_match": {
"query": "你好",
"fields": ["desc", "nickname"]
}
},{
"term": {
"sex": 0
}
}
],
"should": [
{
"match": {
"desc": "我 "
}
}
]
}
}
}
must: 表示同时满足对应的词汇才会被搜索出来(相当于mysql的AND) must_not: 表示所有词汇都不满足才会被搜索出来 (相当于MySQL的not) should: 表示所有词汇只要满足一个就会被搜索出来(相当于MySQL的or)
有时候我们想把分数较低的词汇排名靠前,可以是boost属性为这个词汇加权,使用方法见下方示例:
{
"query": {
"bool": {
"should": [
{
"match": {
"query": "你好",
"boost": 2
}
},{
"match": {
"query": "律师",
"boost": 10
}
}
]
}
}
}
过滤器
过滤器,顾名思义可以在数据集合中过滤出自己想要的数据,比如过滤数据中金额在50~60之间的数据。
{
"query": {
"match": {
"desc": "五子棋游戏"
}
},
"post_filter": {
"range": {
"money": {
"gt": 50,
"lt": 60
}
}
}
}
上面参数中,post_filter表示过滤的意思,与query平级;range表示范围查询,money是mapping的一个字段。 gt:大于,lt:小于,gte:大于等于,lte:小于等于
排序
{
"query": {
"match": {
"desc": "五子棋游戏"
}
},
"sort": [
{
"age": "desc"
}
]
}
支持分词的字段,是不能进行排序的,比如text类型的字段,如果要对这个字段进行排序,可以为这个字段添加一个附属的属性用于排序,可以参考下面创建mapping的例子:
{
"properties": {
"id": {
"type": "long"
},
"nickname": {
"type": "text",
"analyzer": "ik_max_word",
"fields": {
"keyword": { # 这里的keyword,如果下面有text类型的字段需要排序也可以取相同的名字
"type": "keyword"
}
}
}
}
}
创建好可以排序的text类型的字段后,在使用这个字段排序时,需要使用如下方式去排序:
{
"sort": [
{
"nickname.keyword": "desc"
}
]
}
这里的nickname是字段名称,keyword是这个字段的附属属性的名称。
搜索出的数据中匹配的词汇高亮
在我们搜索出来的数据,是根据查询的字符串分词后的词汇匹配出来的,我们可以将这些词汇进行高亮显示。 使用高亮显示的方式如下:
{
"query": {
"match": {
"desc": "五子棋游戏"
}
},
"highlight": { # 高亮显示配置
"pre_tags": ["<span>"], # 高亮显示的词汇前置标签
"post_tags": ["</span>"], # 高亮显示的词汇结束标签
"fields": {
"desc": {} # 高亮显示的字段
}
}
}