Elasticsearch的DSL搜索
一、数据准备
1.创建对应的索引库
2.给索引库创建对应的映射
POST 192.168.1.117:9200/sell/_mapping
{
"properties": {
"id": {
"type": "long"
},
"age": {
"type": "integer"
},
"username": {
"type": "keyword" // 该字段不会被分词,如果需要查询输入的内容必须和字段内容一致
},
"nickname": {
"type": "text",
"analyzer": "ik_max_word" //ik分词器的分词策略
},
"money": {
"type": "float"
},
"desc": {
"type": "text",
"analyzer": "ik_max_word"
},
"sex": {
"type": "byte"
},
"birthday": {
"type": "date"
},
"face": {
"type": "text",
"index": false // 不以该字段内容作为索引进行查询
}
}
}
3.录入对应的数据(这里就提供一条样例)
POST 192.168.1.117:9200/sell/_doc/1001
{
"id": 1001,
"age": 12,
"username": "justsoso",
"nickname": "阿童木",
"money": "34.1",
"desc": "铁臂阿童木拯救世界",
"sex": 1,
"birthday": "1997-12-22",
"face": "https://www.bejson.com/kuaikuai.php"
}
4.使用QueryString方式进行搜索
GET 192.168.1.117:9200/sell/_search?q=desc:詹姆斯
5.使用DSL方式查询数据
根据词语搜索对应的内容
POST 192.168.1.117:9200/sell/_doc/_search
{
"query": {
"match": {
"desc": "詹姆斯"
}
}
}
判断字段是否存在,存在的话就返回对应的内容,没有的话就返回空
POST 192.168.1.117:9200/sell/_doc/_search
{
"query": {
"exists": {
"field": "username"
}
}
}
查询索引库中的所有数据
POST 192.168.1.117:9200/sell/_doc/_search
{
"query": {
"match_all": {}
}
}
自定义返回的字段
POST 192.168.1.117:9200/sell/_doc/_search
{
"query": {
"match_all": {}
},
"_source": [
"id",
"nickname",
"age"
]
}
自定义返回的字段,并且设置分页
POST 192.168.1.117:9200/sell/_doc/_search
{
"query": {
"match_all": {}
},
"_source": [
"id",
"nickname",
"age"
],
"from": 0,
"size": 10
}
使用term方式搜索,例如我们在IK分词器中设置:詹姆斯,詹,姆斯;三个词语,如果我们使用match搜索这个词语就会被分成上面三个词语进行搜索,如过使用term该词条就不会被进行分词搜索
POST 192.168.1.117:9200/sell/_doc/_search
{
"query": {
"term": {
"desc": "詹姆斯"
}
}
}
使用term来进行多个词条搜索
POST 192.168.1.117:9200/sell/_doc/_search
{
"query": {
"terms": {
"desc": ["詹姆斯", "哪吒", "VAVA"]
}
}
}
match_phrase搜索,在query中写的内容,对应的内容同时要包含 “我们” 和 “热爱”,并且包含内容必须是“我们热爱”,如果是 “热爱我们”,或者是中间有别的字在例如“我们的热爱”,就搜索不到,
POST 192.168.1.117:9200/sell/_doc/_search
{
"query": {
"match_phrase": {
"desc": {
"query": "我们 热爱"
}
}
},
"_source": [
"id",
"nickname",
"desc"
]
}
match_phrase搜索,使用slop跳过字段搜索到对应的内容,例如的搜索条件是:“我们 大学”,目标内容是:“我们热爱学习,所以我要上大学”,正常来时是搜索不到的,因为这两个词语之间隔了8个字,但是我们可以使用 slop,例如:“slop”: 8,他的意思就是跳过8个字,刚好是间隔变为0个字,就可以正常命中目标了
POST 192.168.1.117:9200/sell/_doc/_search
{
"query": {
"match_phrase": {
"desc": {
"query": "我们 大学",
"slop": 8
}
}
},
"_source": [
"id",
"nickname",
"desc"
]
}
match搜索的扩展"or"和"and",当operator是"and"的时候,就必须两个词条必须都存在某条数据中,没有顺序要求,如果是"or"的话就只需要有一个词条匹配到就可以了
POST 192.168.1.117:9200/sell/_doc/_search
{
"query": {
"match": {
"desc": {
"query": "我们 詹姆斯",
"operator": "and"
}
}
}
}
match搜索的扩展"minimum_should_match",可以设置匹配度和匹配的格式,例如"我们真的很喜欢詹姆斯打篮球",这句话作为搜索条件,会被进行分词,如果minimum_should_match设置为60%,就是,索引库中的文档分词后和搜索条件的词条匹配度能达到60%就算是命中目标,或者minimum_should_match也可以是 1,就是目标和搜索词条的分词只有有1个一致,就算符合条件
POST 192.168.1.117:9200/sell/_doc/_search
{
"query": {
"match": {
"desc": {
"query": "我们 大学",
"minimum_should_match": 1
}
}
}
}
match搜索的扩展"ids",通过id数组查询数据
POST 192.168.1.117:9200/sell/_doc/_search
{
"query": {
"ids": {
"type": "_doc",
"values": ["1001", "1003", "1011"]
}
}
}
一个查询条件同时从两个字段中查询内容,还可以设置boost权重,权重越高,他的展示的排名越靠前,如果desc的文字内容比nickname的文字内容多,desc的权重会比nickname高,如果我们需要nickname权重增加可以通过""进行操作,"10"权重增加10
POST 192.168.1.117:9200/sell/_doc/_search
{
"query": {
"multi_match": {
"query": "詹姆斯",
"fields": [
"desc", "nickname^10"
]
}
}
}
bool查询:must;multi_match和term是两个查询条条件,must就表示内容只有同时符合这两个条件才能被查出来
POST 192.168.1.117:9200/sell/_doc/_search
{
"query": {
"bool": {
"must": [
{
"multi_match": {
"query": "詹姆斯",
"fields": ["desc", "nickname"]
}
},
{
"term": {
"sex": 1
}
}
]
}
},
"_source": [
"id",
"sex",
"nickname",
"desc"
]
}
bool查询:should;multi_match和term是两个查询条条件,should就表示内容只要满足其中一个内容就能被查询出来
POST 192.168.1.117:9200/sell/_doc/_search
{
"query": {
"bool": {
"should": [
{
"multi_match": {
"query": "詹姆斯",
"fields": ["desc", "nickname"]
}
},
{
"term": {
"sex": 1
}
}
]
}
},
"_source": [
"id",
"sex",
"nickname",
"desc"
]
}
bool查询:must_not;multi_match和term是两个查询条条件,must_not都不满足这两个条件就能被查询出来
POST 192.168.1.117:9200/sell/_doc/_search
{
"query": {
"bool": {
"must_not": [
{
"multi_match": {
"query": "詹姆斯",
"fields": ["desc", "nickname"]
}
},
{
"term": {
"sex": 1
}
}
]
}
},
"_source": [
"id",
"sex",
"nickname",
"desc"
]
}
bool查询的组合查询,must里的条件必须存在,should中的条件可有可无,must_not的条件必须不存在
POST 192.168.1.117:9200/sell/_doc/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"desc": "詹姆斯"
}
}
],
"should": [
{
"match": {
"sex": 0
}
}
],
"must_not": [
{
"term": {
"birthday": "1992-12-12"
}
}
]
}
},
"_source": [
"id",
"sex",
"nickname",
"desc"
]
}
bool查询的组合查询,设置权重:“boost”: 2;权重越大排序越靠前
POST 192.168.1.117:9200/sell/_doc/_search
{
"query": {
"bool": {
"should": [
{
"match": {
"desc": {
"query": "詹姆斯",
"boost": 2
}
}
},
{
"match": {
"desc": {
"query": "大学",
"boost": 20
}
}
}
]
}
},
"_source": [
"id",
"sex",
"nickname",
"desc"
]
}
过滤器:post_filter;先通过query检索出对应的内容再通过post_filter过滤器过滤掉不符合条件的内容;(gt: 大于;lt: 小于;gte:大于等于;lte:小于等于)
POST 192.168.1.117:9200/sell/_doc/_search
{
"query": {
"match": {
"desc": "詹姆斯"
}
},
"post_filter": {
"range": {
"money": {
"gt": 0,
"lt": 1000
}
}
}
}
排序:sort;asc:升序,desc:降序
POST 192.168.1.117:9200/sell/_doc/_search
{
"query": {
"match": {
"desc": "詹姆斯"
}
},
"sort": [
{
"money": "desc"
},
{
"age": "asc"
}
]
}
使用text类型进行排序是会报错的,如果一定要使用text进行排序就需要给他添加一个新的属性:keyword
1.创建对应属性的索引库和映射
POST 192.168.1.117:9200/sell2/_mapping
{
"properties": {
"id": {
"type": "long"
},
"nickname": {
"type": "text",
"analyzer": "ik_max_word",
"fields": {
"keyword": {
"type": "keyword"
}
}
}
}
}
2.插入数据(只举一条例子)
POST 192.168.1.117:9200/sell2/_doc
{
"id": 1001,
"nickname": "詹姆斯"
}
使用nickname的keyword属性进行排序
POST 192.168.1.117:9200/sell2/_doc/_search
{
"sort": [
{
"nickname.keyword": "desc"
}
]
}
搜索高亮显示,拼装分词的前后缀,pre_tags:前缀;post_tags:后缀
POST 192.168.1.117:9200/sell/_doc/_search
{
"query": {
"match": {
"desc": "詹姆斯"
}
},
"highlight": {
"pre_tags": ["<span>"],
"post_tags": ["</span>"],
"fields": {
"desc": {}
}
}
}