java term_[ElasticSearch]Java API 之 词条查询(Term Level Query)
1. 詞條查詢(Term Query)
詞條查詢是ElasticSearch的一個(gè)簡單查詢。它僅匹配在給定字段中含有該詞條的文檔,而且是確切的、未經(jīng)分析的詞條。term
查詢?會查找我們設(shè)定的準(zhǔn)確值。term 查詢本身很簡單,它接受一個(gè)字段名和我們希望查找的值。
下面代碼查詢將匹配 college 字段中含有"California"一詞的文檔。記住,詞條查詢是未經(jīng)分析的,因此需要提供跟索引文檔中的詞條完全匹配的詞條。請注意,我們使用小寫開頭的california來搜索,而不是California,因?yàn)镃alifornia一詞在建立索引時(shí)已經(jīng)變成了california(默認(rèn)分詞器)。
/**
publicstaticvoidtermQuery(Clientclient,Stringindex,Stringtype){
// Query
TermQueryBuildertermQueryBuilder =QueryBuilders.termQuery("country","AWxhOn".toLowerCase());
// Search
SearchRequestBuildersearchRequestBuilder =client.prepareSearch(index);
.setTypes(type);
.setQuery(termQueryBuilder);
// 執(zhí)行
SearchResponsesearchResponse =searchRequestBuilder.get();
// 結(jié)果
(searchResponse);
}
2. 多詞條查詢(Terms Query)
詞條查詢(Term Query)允許匹配單個(gè)未經(jīng)分析的詞條,多詞條查詢(Terms Query)可以用來匹配多個(gè)這樣的詞條。只要指定字段包含任一我們給定的詞條,就可以查詢到該文檔。
下面代碼得到所有在 country 字段中含有 “德國” 或?"比利時(shí)" 的文檔。
/**
publicstaticvoidtermsQuery(Clientclient,Stringindex,Stringtype){
// Query
TermsQueryBuildertermsQueryBuilder =QueryBuilders.termsQuery("country","比利時(shí)","德國");
// Search
SearchRequestBuildersearchRequestBuilder =client.prepareSearch(index);
.setTypes(type);
.setQuery(termsQueryBuilder);
// 執(zhí)行
SearchResponsesearchResponse =searchRequestBuilder.get();
// 結(jié)果
(searchResponse);
}
輸出結(jié)果:
.sjf.open.api.QueryAPI-----------QueryAPIid 9score 0.4898842source {country=比利時(shí),name=阿扎爾,club=切爾西俱樂部}
.sjf.open.api.QueryAPI-----------QueryAPIid 4score 0.39103588source {country=德國,name=穆勒,club=拜仁慕尼黑俱樂部}
.sjf.open.api.QueryAPI-----------QueryAPIid 1score 0.25427115source {country=比利時(shí),name=德布勞內(nèi),club=曼城俱樂部}
3. 范圍查詢(Range Query)
范圍查詢使我們能夠找到在某一字段值在某個(gè)范圍里的文檔,字段可以是數(shù)值型,也可以是基于字符串的。范圍查詢只能針對單個(gè)字段。
方法:
(1)gte() :范圍查詢將匹配字段值大于或等于此參數(shù)值的文檔。
(2)gt() :范圍查詢將匹配字段值大于此參數(shù)值的文檔。
(3)lte() :范圍查詢將匹配字段值小于或等于此參數(shù)值的文檔。
(4)lt() :范圍查詢將匹配字段值小于此參數(shù)值的文檔。
(5)from()
開始值 ?to() 結(jié)束值 ?這兩個(gè)函數(shù)與includeLower()和includeUpper()函數(shù)配套使用。
includeLower(true) 表示 from()?查詢將匹配字段值大于或等于此參數(shù)值的文檔;
includeLower(false) 表示 from()?查詢將匹配字段值大于此參數(shù)值的文檔;
includeUpper(true) 表示 to()?查詢將匹配字段值小于或等于此參數(shù)值的文檔;
includeUpper(false) 表示 to()?查詢將匹配字段值小于此參數(shù)值的文檔;
/**
publicstaticvoidrangeQuery(Clientclient,Stringindex,Stringtype){
// Query
RangeQueryBuilderrangeQueryBuilder =QueryBuilders.rangeQuery("age");
.from(19);
.to(21);
.includeLower(true);
.includeUpper(true);
//RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("age").gte(19).lte(21);
// Search
SearchRequestBuildersearchRequestBuilder =client.prepareSearch(index);
.setTypes(type);
.setQuery(rangeQueryBuilder);
// 執(zhí)行
SearchResponsesearchResponse =searchRequestBuilder.execute().actionGet();
// 結(jié)果
(searchResponse);
}
上面代碼中的查詢語句與下面的是等價(jià)的:
QueryBuilderqueryBuilder =QueryBuilders.rangeQuery("age").gte(19).lte(21);
輸出結(jié)果:
.sjf.open.api.QueryAPI-----------QueryAPIid 9score 1.0source {college=計(jì)算機(jī)學(xué)院,school=麻省理工大學(xué),sex=boy,name=廖力生,age=21}
.sjf.open.api.QueryAPI-----------QueryAPIid 2score 1.0source {college=通信學(xué)院,school=西安電子科技大學(xué),sex=boy,name=李源一,age=19}
.sjf.open.api.QueryAPI-----------QueryAPIid 4score 1.0source {college=電子工程學(xué)院,school=中國科技大學(xué),sex=girl,name=王俊輝,age=21}
.sjf.open.api.QueryAPI-----------QueryAPIid 1score 1.0source {college=計(jì)算機(jī)學(xué)院,school=西安電子科技大學(xué),sex=boy,name=徐欣,age=21}
.sjf.open.api.QueryAPI-----------QueryAPIid 11score 1.0source {college=計(jì)算機(jī)學(xué)院ddddd,school=中國科技大學(xué),sex=girl,name=王俊輝2,age=21}
4. 存在查詢(Exists Query)
如果指定字段上至少存在一個(gè)no-null的值就會返回該文檔。
/**
publicstaticvoidexistsQuery(Clientclient,Stringindex,Stringtype){
// Query
ExistsQueryBuilderexistsQueryBuilder =QueryBuilders.existsQuery("name");
// Search
SearchRequestBuildersearchRequestBuilder =client.prepareSearch(index);
.setTypes(type);
.setQuery(existsQueryBuilder);
// 執(zhí)行
SearchResponsesearchResponse =searchRequestBuilder.get();
// 結(jié)果
(searchResponse);
}
舉例說明,下面的幾個(gè)文檔都會得到上面代碼的匹配:
第一個(gè)是字符串,是一個(gè)非null的值。
第二個(gè)是空字符串,也是非null。
第三個(gè)使用標(biāo)準(zhǔn)分析器的情況下盡管不會返回詞條,但是原始字段值是非null的(Even though the?standard?analyzer would emit zero tokens, the original field is non-null)。
第五個(gè)中至少有一個(gè)是非null值。
下面幾個(gè)文檔不會得到上面代碼的匹配:
"bar"}
第一個(gè)是null值。
第二個(gè)沒有值。
第三個(gè)只有null值,至少需要一個(gè)非null值。
第四個(gè)與指定字段不匹配。
5. 前綴查詢(Prefix Query)
前綴查詢讓我們匹配這樣的文檔:它們的特定字段已給定的前綴開始。下面代碼中我們查詢所有country字段以"葡萄"開始的文檔。
/**
publicstaticvoidprefixQuery(Clientclient,Stringindex,Stringtype){
// Query
PrefixQueryBuilderprefixQueryBuilder =QueryBuilders.prefixQuery("country","葡萄");
// Search
SearchRequestBuildersearchRequestBuilder =client.prepareSearch(index);
.setTypes(type);
.setQuery(prefixQueryBuilder);
// 執(zhí)行
SearchResponsesearchResponse =searchRequestBuilder.get();
// 結(jié)果
(searchResponse);
}
輸出結(jié)果:
.sjf.open.api.QueryAPI-----------QueryAPIid 3score 1.0source {country=葡萄牙,name=C羅,club=皇家馬德里俱樂部}
備注:
進(jìn)行下面前綴查詢,沒有查找到相應(yīng)信息,但是數(shù)據(jù)源中是有的:
QueryBuilderqueryBuilder =QueryBuilders.prefixQuery("club","皇家馬德里");
產(chǎn)生以上差別的主要原因是club字段(默認(rèn)mapping配置)進(jìn)行了分析器分析了,索引中的數(shù)據(jù)已經(jīng)不在是"皇家馬德里",而country字段沒有進(jìn)行分析(mapping配置not_analyzed)。
6. 通配符查詢(Wildcard Query)
通配符查詢允許我們獲取指定字段滿足通配符表達(dá)式的文檔,和前綴查詢一樣,通配符查詢指定字段是未分析的(not analyzed)。
可以使用星號代替0個(gè)或多個(gè)字符,使用問號代替一個(gè)字符。星號表示匹配的數(shù)量不受限制,而后者的匹配字符數(shù)則受到限制。這個(gè)技巧主要用于英文搜索中,如輸入““computer*”,就可以找到“computer、computers、computerised、computerized”等單詞,而輸入“comp?ter”,則只能找到“computer、compater、competer”等單詞。注意的是通配符查詢不太注重性能,在可能時(shí)盡量避免,特別是要避免前綴通配符(以以通配符開始的詞條)。
/**
publicstaticvoidwildcardQuery(Clientclient,Stringindex,Stringtype){
// Query
WildcardQueryBuilderwildcardQueryBuilder =QueryBuilders.wildcardQuery("country","西*牙");
// Search
SearchRequestBuildersearchRequestBuilder =client.prepareSearch(index);
.setTypes(type);
.setQuery(wildcardQueryBuilder);
// 執(zhí)行
SearchResponsesearchResponse =searchRequestBuilder.get();
// 結(jié)果
(searchResponse);
}
輸出結(jié)果:
.sjf.open.api.queryAPI.TermQueryAPI-----------TermQueryAPIid 8score 1.0source {country=西班牙,name=托雷斯,club=馬德里競技俱樂部}
.sjf.open.api.queryAPI.TermQueryAPI-----------TermQueryAPIid 6score 1.0source {country=西班牙,name=布斯克茨,club=巴薩羅那俱樂部}
.sjf.open.api.queryAPI.TermQueryAPI-----------TermQueryAPIid 7score 1.0source {country=西班牙,name=哈維,club=巴薩羅那俱樂部}
7. 正則表達(dá)式查詢(Regexp Query)
正則表達(dá)式查詢允許我們獲取指定字段滿足正則表達(dá)式的文檔,和前綴查詢一樣,正則表達(dá)式查詢指定字段是未分析的(not analyzed)。正則表達(dá)式查詢的性能取決于所選的正則表達(dá)式。如果我們的正則表達(dá)式匹配許多詞條,查詢將很慢。一般規(guī)則是,正則表達(dá)式匹配的詞條數(shù)越高,查詢越慢。
/**
publicstaticvoidregexpQuery(Clientclient,Stringindex,Stringtype){
// Query
RegexpQueryBuilderregexpQueryBuilder =QueryBuilders.regexpQuery("country","(西班|葡萄)牙");
// Search
SearchRequestBuildersearchRequestBuilder =client.prepareSearch(index);
.setTypes(type);
.setQuery(regexpQueryBuilder);
// 執(zhí)行
SearchResponsesearchResponse =searchRequestBuilder.get();
// 結(jié)果
(searchResponse);
}
輸出結(jié)果:
.sjf.open.api.queryAPI.TermQueryAPI-----------TermQueryAPIid 8score 1.0source {country=西班牙,name=托雷斯,club=馬德里競技俱樂部}
.sjf.open.api.queryAPI.TermQueryAPI-----------TermQueryAPIid 6score 1.0source {country=西班牙,name=布斯克茨,club=巴薩羅那俱樂部}
.sjf.open.api.queryAPI.TermQueryAPI-----------TermQueryAPIid 7score 1.0source {country=西班牙,name=哈維,club=巴薩羅那俱樂部}
.sjf.open.api.queryAPI.TermQueryAPI-----------TermQueryAPIid 3score 1.0source {country=葡萄牙,name=C羅,club=皇家馬德里俱樂部}
8. 模糊查詢(Fuzzy Query)
如果指定的字段是string類型,模糊查詢是基于編輯距離算法來匹配文檔。編輯距離的計(jì)算基于我們提供的查詢詞條和被搜索文檔。如果指定的字段是數(shù)值類型或者日期類型,模糊查詢基于在字段值上進(jìn)行加減操作來匹配文檔(The fuzzy query uses
similarity based on Levenshtein edit distance for?fields,
and a?margin
on numeric and date fields)。此查詢很占用CPU資源,但當(dāng)需要模糊匹配時(shí)它很有用,例如,當(dāng)用戶拼寫錯(cuò)誤時(shí)。另外我們可以在搜索詞的尾部加上字符 “~” 來進(jìn)行模糊查詢。
8.1 string類型字段
模糊查詢生成所有可能跟指定詞條的匹配結(jié)果(在fuzziness指定的最大編輯距離范圍之內(nèi))。然后檢查生成的所有結(jié)果是否是在索引中。
下面代碼中模糊查詢country字段為”西班牙“的所有文檔,同時(shí)指定最大編輯距離為1(fuzziness),最少公共前綴為0(prefixLength),即不需要公共前綴。
/**
publicstaticvoidfuzzyQuery(Clientclient,Stringindex,Stringtype){
// Query
FuzzyQueryBuilderfuzzyQueryBuilder =QueryBuilders.fuzzyQuery("country","洗班牙");
// 最大編輯距離
.fuzziness(Fuzziness.ONE);
// 公共前綴
.prefixLength(0);
// Search
SearchRequestBuildersearchRequestBuilder =client.prepareSearch(index);
.setTypes(type);
.setQuery(fuzzyQueryBuilder);
// 執(zhí)行
SearchResponsesearchResponse =searchRequestBuilder.get();
// 結(jié)果
(searchResponse);
}
輸出結(jié)果:
.sjf.open.api.queryAPI.TermQueryAPI-----------TermQueryAPIid 8score 1.6931472source {country=西班牙,name=托雷斯,club=馬德里競技俱樂部}
.sjf.open.api.queryAPI.TermQueryAPI-----------TermQueryAPIid 6score 1.4054651source {country=西班牙,name=布斯克茨,club=巴薩羅那俱樂部}
.sjf.open.api.queryAPI.TermQueryAPI-----------TermQueryAPIid 7score 1.0source {country=西班牙,name=哈維,club=巴薩羅那俱樂部}
8.2 數(shù)字和日期類型字段
與范圍查詢(Range Query)的around比較類似。形成在指定值上上下波動(dòng)fuzziness大小的一個(gè)范圍:
field value <=+fuzziness
下面代碼在18歲上下波動(dòng)2歲,形成[17-19]的一個(gè)范圍查詢:
/**
publicstaticvoidfuzzyQuery2(Clientclient,Stringindex,Stringtype){
// Query
FuzzyQueryBuilderfuzzyQueryBuilder =QueryBuilders.fuzzyQuery("age","18");
.fuzziness(Fuzziness.TWO);
// Search
SearchRequestBuildersearchRequestBuilder =client.prepareSearch(index);
.setTypes(type);
.setQuery(fuzzyQueryBuilder);
// 執(zhí)行
SearchResponsesearchResponse =searchRequestBuilder.get();
// 結(jié)果
(searchResponse);
}
總結(jié)
以上是生活随笔為你收集整理的java term_[ElasticSearch]Java API 之 词条查询(Term Level Query)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java swftools linux_
- 下一篇: java 生成sql脚本_java导出i