Query DSL
Elasticsearch 提供了基于 JSON 的完整 Query DSL(Domain Specific Language)來(lái)定義查詢(xún)。
因Query DSL是利用Rest API傳遞JSON格式的請(qǐng)求體(RequestBody)數(shù)據(jù)與ES進(jìn)行交互,所以我們?cè)谑褂胹pringboot的時(shí)候也可以很方便的進(jìn)行集成,本文主要講述的就是使用springboot實(shí)現(xiàn)各類(lèi)DSL的語(yǔ)法查詢(xún)。
Elasticsearch 官網(wǎng)地址
數(shù)據(jù)準(zhǔn)備
新增名為(dsl_index)的索引,并插入部分?jǐn)?shù)據(jù),本文使用springboot變更Elasticsearch數(shù)據(jù)都是通過(guò)RestHighLevelClient來(lái)操作的
索引(dsl_index)結(jié)構(gòu):
GET dsl_index/_mappings
{
"dsl_index" : {
"mappings" : {
"properties" : {
"age" : {
"type" : "long"
},
"description" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"name" : {
"type" : "text",
"analyzer" : "ik_max_word",
"search_analyzer" : "ik_smart"
}
}
}
}
}
索引(dsl_index)數(shù)據(jù):
POST /dsl_index/_bulk
{"index":{"_id":1}}
{"name":"張三","age":11,"description":"南京市 羽毛球愛(ài)好者"}
{"index":{"_id":2}}
{"name":"王五","age":15,"description":"北京市 籃球兩年半"}
{"index":{"_id":3}}
{"name":"李四","age":18,"description":"山東省 游泳健身"}
{"index":{"_id":4}}
{"name":"富貴","age":22,"description":"天津市 游泳打球"}
{"index":{"_id":5}}
{"name":"來(lái)福","age":8,"description":"安徽合肥 職業(yè)代練"}
{"index":{"_id":6}}
{"name":"憨憨","age":27,"description":"北京市 健身打球"}
{"index":{"_id":7}}
{"name":"小七","age":31,"description":"北京市 游泳"}
match_all
match_all會(huì)查詢(xún)指定索引下的所有文檔,但是默認(rèn)只會(huì)返回10條數(shù)據(jù)。原因是:_search查詢(xún)默認(rèn)采用的是分頁(yè)查詢(xún),from=0;size=10 如果想顯示更多數(shù)據(jù),指定size數(shù)量
DSL: 查詢(xún)當(dāng)前索引下所有數(shù)據(jù)(默認(rèn)前十條)
GET dsl_index/_search
{
"query": {
"match_all": {}
}
}
返回?cái)?shù)據(jù)如下:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 7,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "dsl_index",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"name" : "張三",
"age" : 11,
"description" : "南京市 羽毛球愛(ài)好者"
}
},
{
"_index" : "dsl_index",
"_type" : "_doc",
"_id" : "2",
"_score" : 1.0,
"_source" : {
"name" : "王五",
"age" : 15,
"description" : "北京市 籃球兩年半"
}
},
{
"_index" : "dsl_index",
"_type" : "_doc",
"_id" : "3",
"_score" : 1.0,
"_source" : {
"name" : "李四",
"age" : 18,
"description" : "山東省 游泳健身"
}
},
{
"_index" : "dsl_index",
"_type" : "_doc",
"_id" : "4",
"_score" : 1.0,
"_source" : {
"name" : "富貴",
"age" : 22,
"description" : "天津市 游泳打球"
}
},
{
"_index" : "dsl_index",
"_type" : "_doc",
"_id" : "5",
"_score" : 1.0,
"_source" : {
"name" : "來(lái)福",
"age" : 8,
"description" : "安徽合肥 職業(yè)代練"
}
},
{
"_index" : "dsl_index",
"_type" : "_doc",
"_id" : "6",
"_score" : 1.0,
"_source" : {
"name" : "憨憨",
"age" : 27,
"description" : "北京市 健身打球"
}
},
{
"_index" : "dsl_index",
"_type" : "_doc",
"_id" : "7",
"_score" : 1.0,
"_source" : {
"name" : "小七",
"age" : 31,
"description" : "北京市 游泳"
}
}
]
}
}
sprongboot實(shí)現(xiàn):
代碼:
private static final String INDEX_NAME = "dsl_index"; -- 以下統(tǒng)一使用該索引
@Resource
private RestHighLevelClient client; -- 以下統(tǒng)一使用該client
@RequestMapping(value = "/matchAll", method = RequestMethod.GET)
@ApiOperation(value = "DSL - match_all")
public void matchAll() throws Exception {
// 定義請(qǐng)求對(duì)象
SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
// 查詢(xún)所有
searchRequest.source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()));
// 打印返回?cái)?shù)據(jù)
printLog(client.search(searchRequest, RequestOptions.DEFAULT));
}
查詢(xún)結(jié)果如下:
{name=張三, description=南京市 羽毛球愛(ài)好者, age=11}
{name=王五, description=北京市 籃球兩年半, age=15}
{name=李四, description=山東省 游泳健身, age=18}
{name=富貴, description=天津市 游泳打球, age=22}
{name=來(lái)福, description=安徽合肥 職業(yè)代練, age=8}
{name=憨憨, description=北京市 健身打球, age=27}
{name=小七, description=北京市 游泳, age=31}
術(shù)語(yǔ)級(jí)查詢(xún)
官網(wǎng)地址
術(shù)語(yǔ)級(jí)別查詢(xún)(Term-Level Queries)指的是搜索內(nèi)容不經(jīng)過(guò)文本分析直接用于文本匹配,這個(gè)過(guò)程類(lèi)似于數(shù)據(jù)庫(kù)的SQL查詢(xún),搜索的對(duì)象大多是索引的非text類(lèi)型字段。
Term Query
術(shù)語(yǔ)查詢(xún)直接返回包含搜索內(nèi)容的文檔,常用來(lái)查詢(xún)索引中某個(gè)類(lèi)型為keyword的文本字段,類(lèi)似于SQL的“=”查詢(xún),因此最好不要在term查詢(xún)的字段中使用text字段,因?yàn)閠ext字段會(huì)被分詞,這樣做既沒(méi)有意義,還很有可能什么也查不到。
DSL: 查詢(xún)當(dāng)前索引下age=31的數(shù)據(jù)
GET dsl_index/_search
{
"query": {
"term": {
"age": {
"value": "31"
}
}
}
}
返回?cái)?shù)據(jù)如下:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "dsl_index",
"_type" : "_doc",
"_id" : "7",
"_score" : 1.0,
"_source" : {
"name" : "小七",
"age" : 31,
"description" : "北京市 游泳"
}
}
]
}
}
springboot實(shí)現(xiàn):
代碼如下:
@RequestMapping(value = "/term", method = RequestMethod.GET)
@ApiOperation(value = "DSL - term")
public void term() throws Exception {
// 定義請(qǐng)求對(duì)象
SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
// 查詢(xún)
searchRequest.source(new SearchSourceBuilder().query(QueryBuilders.termQuery("age",31)));
// 打印返回?cái)?shù)據(jù)
printLog(client.search(searchRequest, RequestOptions.DEFAULT));
}
查詢(xún)結(jié)果如下:
{name=小七, description=北京市 游泳, age=31}
Terms Query
Terms query用于在指定字段上匹配多個(gè)詞項(xiàng)(terms)。它會(huì)精確匹配指定字段中包含的任何一個(gè)詞項(xiàng)。
DSL: 查詢(xún)當(dāng)前索引中age 為31或者15的數(shù)據(jù),類(lèi)似mysql的age in (‘15’,‘31’)
GET dsl_index/_search
{
"query": {
"terms": {
"age": ["31","15"]
}
}
}
返回結(jié)果如下:
{
"took" : 13,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "dsl_index",
"_type" : "_doc",
"_id" : "2",
"_score" : 1.0,
"_source" : {
"name" : "王五",
"age" : 15,
"description" : "北京市 籃球兩年半"
}
},
{
"_index" : "dsl_index",
"_type" : "_doc",
"_id" : "7",
"_score" : 1.0,
"_source" : {
"name" : "小七",
"age" : 31,
"description" : "北京市 游泳"
}
}
]
}
}
springboot實(shí)現(xiàn):
@RequestMapping(value = "/terms", method = RequestMethod.GET)
@ApiOperation(value = "DSL - terms")
public void terms() throws Exception {
// 定義請(qǐng)求對(duì)象
SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
// 查詢(xún)
searchRequest.source(new SearchSourceBuilder().query(QueryBuilders.termsQuery("age", new String[]{"15", "31"})));
// 打印返回?cái)?shù)據(jù)
printLog(client.search(searchRequest, RequestOptions.DEFAULT));
}
返回結(jié)果如下:
{name=王五, description=北京市 籃球兩年半, age=15}
{name=小七, description=北京市 游泳, age=31}
Exists Query
在Elasticsearch中可以使用exists進(jìn)行查詢(xún),判斷文檔中是否存在對(duì)應(yīng)的字段。
DSL: 判斷當(dāng)前索引中是否存在sex字段
GET dsl_index/_search
{
"query": {
"exists": {
"field": "sex"
}
}
}
返回結(jié)果如下: 很明顯返回值hits中并無(wú)數(shù)據(jù),說(shuō)明當(dāng)前索引中沒(méi)有sex字段
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 0,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
}
}
springboot實(shí)現(xiàn):
@RequestMapping(value = "/exists", method = RequestMethod.GET)
@ApiOperation(value = "DSL - exists")
public void exists() throws Exception {
// 定義請(qǐng)求對(duì)象
SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
// 查詢(xún)
searchRequest.source(new SearchSourceBuilder().query(QueryBuilders.existsQuery("sex")));
// 打印返回?cái)?shù)據(jù)
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT)
SearchHits hits = searchResponse.getHits();
System.out.println("返回hits數(shù)組長(zhǎng)度:" + hits.getHits().length);
}
返回結(jié)果如下:
返回hits數(shù)組長(zhǎng)度:0
Ids Query
ids 關(guān)鍵字 : 值為每條文檔的默認(rèn)主鍵,根據(jù)一組id獲取多個(gè)對(duì)應(yīng)的文檔
DSL: 查詢(xún)_id為1或者2的數(shù)據(jù)
GET dsl_index/_search
{
"query": {
"ids": {
"values": [1,2]
}
}
}
返回?cái)?shù)據(jù)如下:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "dsl_index",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"name" : "張三",
"age" : 11,
"description" : "南京市 羽毛球愛(ài)好者"
}
},
{
"_index" : "dsl_index",
"_type" : "_doc",
"_id" : "2",
"_score" : 1.0,
"_source" : {
"name" : "王五",
"age" : 15,
"description" : "北京市 籃球兩年半"
}
}
]
}
}
springboot實(shí)現(xiàn):
@RequestMapping(value = "/ids", method = RequestMethod.GET)
@ApiOperation(value = "DSL - ids")
public void ids() throws Exception {
// 定義請(qǐng)求對(duì)象
SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
// 第一種方式
// searchRequest.source(new SearchSourceBuilder().query(QueryBuilders.termsQuery("_id","1","2")));
// 第二種方式
searchRequest.source(new SearchSourceBuilder().query(QueryBuilders.idsQuery().addIds(new String[]{"1","2"})));
// 打印返回?cái)?shù)據(jù)
printLog(client.search(searchRequest, RequestOptions.DEFAULT));
}
返回結(jié)果如下:
{name=張三, description=南京市 羽毛球愛(ài)好者, age=11}
{name=王五, description=北京市 籃球兩年半, age=15}
Range Query
范圍查詢(xún):
- range:范圍關(guān)鍵字
- gte 大于等于
- lte 小于等于
- gt 大于
- lt 小于
- now 當(dāng)前時(shí)間
DSL: 查詢(xún)當(dāng)前索引下age>=20且age<=30的數(shù)據(jù)
GET dsl_index/_search
{
"query": {
"range": {
"age": {
"gte": 20,
"lte": 30
}
}
}
}
返回?cái)?shù)據(jù)如下:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "dsl_index",
"_type" : "_doc",
"_id" : "4",
"_score" : 1.0,
"_source" : {
"name" : "富貴",
"age" : 22,
"description" : "天津市 游泳打球"
}
},
{
"_index" : "dsl_index",
"_type" : "_doc",
"_id" : "6",
"_score" : 1.0,
"_source" : {
"name" : "憨憨",
"age" : 27,
"description" : "北京市 健身打球"
}
}
]
}
}
springboot:
@RequestMapping(value = "/range", method = RequestMethod.GET)
@ApiOperation(value = "DSL - range")
public void range() throws Exception {
// 定義請(qǐng)求對(duì)象
SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
// 查詢(xún)
searchRequest.source(new SearchSourceBuilder().query(QueryBuilders.rangeQuery("age").gte(20).lte(30)));
// 打印返回?cái)?shù)據(jù)
printLog(client.search(searchRequest, RequestOptions.DEFAULT));
}
返回結(jié)果如下:
{name=富貴, description=天津市 游泳打球, age=22}
{name=憨憨, description=北京市 健身打球, age=27}
Prefix Query
前綴查詢(xún) :
- 它不會(huì)分析要搜索字符串,傳入的前綴就是想要查找的前綴
- prefix的原理:需要遍歷所有倒排索引,并比較每個(gè)term是否以所指定的前綴開(kāi)頭。
此時(shí)當(dāng)前索引中的數(shù)據(jù)如下: - 默認(rèn)狀態(tài)下,前綴查詢(xún)不做相關(guān)度分?jǐn)?shù)計(jì)算,它只是將所有匹配的文檔返回,然后賦予所有相關(guān)分?jǐn)?shù)值為1。它的行為更像是一個(gè)過(guò)濾器而不是查詢(xún)。兩者實(shí)際的區(qū)別就是過(guò)濾器是可以被緩存的,而前綴查詢(xún)不行。
{name=張三, description=南京市 羽毛球愛(ài)好者, age=11}
{name=王五, description=北京市 籃球兩年半, age=15}
{name=李四, description=山東省 游泳健身, age=18}
{name=富貴, description=天津市 游泳打球, age=22}
{name=來(lái)福, description=安徽合肥 職業(yè)代練, age=8}
{name=憨憨, description=北京市 健身打球, age=27}
{name=小七, description=北京市 游泳, age=31}
DSL: 查詢(xún)description以 "南"開(kāi)頭的數(shù)據(jù)
GET dsl_index/_search
{
"query": {
"prefix": {
"description": {
"value": "南"
}
}
}
}
返回?cái)?shù)據(jù)如下:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "dsl_index",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"name" : "張三",
"age" : 11,
"description" : "南京市 羽毛球愛(ài)好者"
}
}
]
}
}
springboot實(shí)現(xiàn):
@RequestMapping(value = "/prefix", method = RequestMethod.GET)
@ApiOperation(value = "DSL - prefix")
public void prefix() throws Exception {
// 定義請(qǐng)求對(duì)象
SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
// 查詢(xún)
searchRequest.source(new SearchSourceBuilder().query(QueryBuilders.prefixQuery("description","南")));
// 打印返回?cái)?shù)據(jù)
printLog(client.search(searchRequest, RequestOptions.DEFAULT));
}
返回?cái)?shù)據(jù)如下:
{name=張三, description=南京市 羽毛球愛(ài)好者, age=11}
疑問(wèn): 查詢(xún)description以 “南” 開(kāi)頭有數(shù)據(jù)返回,查詢(xún) “南京” 開(kāi)頭的無(wú)數(shù)據(jù)返回
DSL:
GET dsl_index/_search
{
"query": {
"prefix": {
"description": {
"value": "南京"
}
}
}
}
返回結(jié)果如下:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 0,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
}
}
原因: 這就是上文說(shuō)到的,prefix的原理是不對(duì)查詢(xún)的數(shù)據(jù)分詞,用查詢(xún)的數(shù)據(jù)直接遍歷所有倒排索引
而我們?cè)趧?chuàng)建索引的時(shí)候,description字段使用的是默認(rèn)分詞器 “standard”,該分詞器會(huì)把輸入的每個(gè)字符單獨(dú)拆分,比方說(shuō)把 "南京市 " 拆分成 “南”,“京”,“市”,顧而通過(guò) “南” 字符去匹配能查詢(xún)到數(shù)據(jù),而通過(guò) “南京” 去匹配無(wú)數(shù)據(jù)
分詞器 “standard” 解析 “南京市” 如下:
POST _analyze
{
"analyzer": "standard",
"text": ["南京市"]
}
結(jié)果如下:
{
"tokens" : [
{
"token" : "南",
"start_offset" : 0,
"end_offset" : 1,
"type" : "<IDEOGRAPHIC>",
"position" : 0
},
{
"token" : "京",
"start_offset" : 1,
"end_offset" : 2,
"type" : "<IDEOGRAPHIC>",
"position" : 1
},
{
"token" : "市",
"start_offset" : 2,
"end_offset" : 3,
"type" : "<IDEOGRAPHIC>",
"position" : 2
}
]
}
那么我們?nèi)绻拖胪ㄟ^(guò) “南京” 去搜索到數(shù)據(jù)如何實(shí)現(xiàn)呢?可以在創(chuàng)建索引的時(shí)候,指定字段分詞器為
“ik_max_word”,該分詞器劃分粒度比較細(xì),當(dāng)然也可以指定其它分詞器或者自定義分詞器,看場(chǎng)景需要,如下是 “ik_max_word” 分詞器解析 “南京市” :
POST _analyze
{
"analyzer": "ik_max_word",
"text": ["南京市"]
}
結(jié)果如下:
{
"tokens" : [
{
"token" : "南京市",
"start_offset" : 0,
"end_offset" : 3,
"type" : "CN_WORD",
"position" : 0
},
{
"token" : "南京",
"start_offset" : 0,
"end_offset" : 2,
"type" : "CN_WORD",
"position" : 1
},
{
"token" : "市",
"start_offset" : 2,
"end_offset" : 3,
"type" : "CN_CHAR",
"position" : 2
}
]
}
Wildcard Query
通配符查詢(xún):工作原理和prefix相同,只不過(guò)它不是只比較開(kāi)頭,它能支持更為復(fù)雜的匹配模式。
注意:其實(shí)無(wú)論是前綴匹配還是通配符查詢(xún),針對(duì)的都是倒排索引。
DSL: 查詢(xún)當(dāng)前索引下description字段中含有 “籃” 的數(shù)據(jù)
GET dsl_index/_search
{
"query": {
"prefix": {
"description": {
"value": "籃"
}
}
}
}
返回結(jié)果如下:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "dsl_index",
"_type" : "_doc",
"_id" : "2",
"_score" : 1.0,
"_source" : {
"name" : "王五",
"age" : 15,
"description" : "北京市 籃球兩年半"
}
}
]
}
}
springboot實(shí)現(xiàn):
@RequestMapping(value = "/wildcard", method = RequestMethod.GET)
@ApiOperation(value = "DSL - wildcard")
public void wildcard() throws Exception {
// 定義請(qǐng)求對(duì)象
SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
// 查詢(xún)
searchRequest.source(new SearchSourceBuilder().query(QueryBuilders.wildcardQuery("description","籃")));
// 打印返回?cái)?shù)據(jù)
printLog(client.search(searchRequest, RequestOptions.DEFAULT));
}
返回結(jié)果如下:
{name=王五, description=北京市 籃球兩年半, age=15}
Fuzzy Query
模糊查詢(xún):
在實(shí)際的搜索中,我們有時(shí)候會(huì)打錯(cuò)字,從而導(dǎo)致搜索不到。在Elasticsearch中,我們可以使用fuzziness屬性來(lái)進(jìn)行模糊查詢(xún),從而達(dá)到搜索有錯(cuò)別字的情形。
fuzzy 查詢(xún)會(huì)用到兩個(gè)很重要的參數(shù),fuzziness,prefix_length
- fuzziness:表示輸入的關(guān)鍵字通過(guò)幾次操作可以轉(zhuǎn)變成為ES庫(kù)里面的對(duì)應(yīng)field的字段
- 操作是指:新增一個(gè)字符,刪除一個(gè)字符,修改一個(gè)字符,每次操作可以記做編輯距離為1;
- 如中文集團(tuán)到中威集團(tuán)編輯距離就是1,只需要修改一個(gè)字符;如果fuzziness值在這里設(shè)置成2,會(huì)把編輯距離為2的東東集團(tuán)也查出來(lái)。
- 該參數(shù)默認(rèn)值為0,即不開(kāi)啟模糊查詢(xún); fuzzy 模糊查詢(xún) 最大模糊錯(cuò)誤必須在0-2之間
- prefix_length:表示限制輸入關(guān)鍵字和ES對(duì)應(yīng)查詢(xún)field的內(nèi)容開(kāi)頭的第n個(gè)字符必須完全匹配,不允許錯(cuò)別字匹配;
- 如這里等于1,則表示開(kāi)頭的字必須匹配,不匹配則不返回;
- 默認(rèn)值也是0;
- 加大prefix_length的值可以提高效率和準(zhǔn)確率。
DSL: 此時(shí)我們索引中有以下的數(shù)據(jù):{name=王五, description=北京市 籃球兩年半, age=15}
我們搜索description字段值為 “北京市 足球兩年半” 故意輸錯(cuò)一個(gè)字符
1.當(dāng)設(shè)置fuzziness=0時(shí):
GET dsl_index/_search
{
"query": {
"fuzzy": {
"description.keyword": {
"value": "北京市 足球兩年半",
"fuzziness": 0
}
}
}
}
無(wú)數(shù)據(jù)返回,如下:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 0,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
}
}
2.當(dāng)設(shè)置fuzziness=1時(shí):
GET dsl_index/_search
{
"query": {
"fuzzy": {
"description.keyword": {
"value": "北京市 足球兩年半",
"fuzziness": 1
}
}
}
}
返回?cái)?shù)據(jù)如下:
{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.4879789,
"hits" : [
{
"_index" : "dsl_index",
"_type" : "_doc",
"_id" : "2",
"_score" : 1.4879789,
"_source" : {
"name" : "王五",
"age" : 15,
"description" : "北京市 籃球兩年半"
}
}
]
}
}
springboot實(shí)現(xiàn):文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-790232.html
搜索description字段值為 "北京市 足球兩年半",并且可以錯(cuò)一個(gè)字符:
@RequestMapping(value = "/fuzzy", method = RequestMethod.GET)
@ApiOperation(value = "DSL - fuzzy")
public void fuzzy() throws Exception {
// 定義請(qǐng)求對(duì)象
SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
// 查詢(xún)
searchRequest.source(new SearchSourceBuilder().query(
QueryBuilders.fuzzyQuery("description.keyword","北京市 籃球2年半").fuzziness(Fuzziness.ONE)));
// 打印返回?cái)?shù)據(jù)
printLog(client.search(searchRequest, RequestOptions.DEFAULT));
}
返回?cái)?shù)據(jù)如下:
{name=王五, description=北京市 籃球兩年半, age=15}
以上就是Query DSL術(shù)語(yǔ)級(jí)別查詢(xún)并結(jié)合springboot的使用方法,后期繼續(xù)介紹全文檢索結(jié)合springboot使用。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-790232.html
到了這里,關(guān)于【ElasticSearch-基礎(chǔ)篇】ES高級(jí)查詢(xún)Query DSL術(shù)語(yǔ)級(jí)別查詢(xún)并結(jié)合springboot使用的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!