DSL 查詢種類
- 查詢所有:查詢所有數(shù)據(jù),一般在測試時(shí)使用。march_all,但是一般顯示全部,有一個(gè)分頁的功能
- 全文檢索(full text)查詢:利用分詞器對用戶的輸入內(nèi)容進(jìn)行分詞,然后去倒排索引庫匹配。例如:
- match_query
- mutil_match_query
- 精確查詢:根據(jù)精確詞條值查詢數(shù)據(jù),一般查找的時(shí)keyword、數(shù)值、日期、boolean等字段。例如:
- ids
- term
- range
- 地理查詢(geo):根據(jù)經(jīng)緯度查詢,例如:
- geo_distance
- geo_bounding_box
- 復(fù)合(compound)查詢:復(fù)合查詢時(shí)將上面各種查詢條件組合在一起,合并查詢條件。例如:
- bool
- funcation_score
DSL query 基本語法
1、全文檢索
# DSL查詢
GET /indexName/_search
{
"query":{
"查詢類型":{
"查詢條件":"條件值"
}
}
}
match 與 multi_match 的與別是前者根據(jù)單字段查,后者根據(jù)多字段查。
參與搜索的字段越多,查詢效率越低,建議利用copy_to將多個(gè)檢索字段放在一起,然后使用match—all字段查。
GET /hotel/_search
{
"query": {
"match": {
"city": "上海"
}
}
}
GET /hotel/_search
{
"query": {
"match": {
"all": "如家"
}
}
}
GET /hotel/_search
{
"query": {
"multi_match": {
"query": "如家",
"fields": ["name","brand","business"]
}
}
}
2、精確查詢
精確查詢: term字段全值匹配,range字段范圍匹配。
精確查詢一般查找keyword、數(shù)值、boolean等不可分詞的字段
# term
GET /hotel/_search
{
"query": {
"term": {
"city": {
"value": "北京"
}
}
}
}
# range
GET /hotel/_search
{
"query": {
"range": {
"price": {
"gt": 1000,
"lt": 2000
}
}
}
}
3、地理查詢
GET /hotel/_search
{
"query": {
"geo_bounding_box": {
"location": {
"top_left": {
"lat": 31.1,
"lon": 121.5
},
"bottom_right": {
"lat": 30.9,
"lon": 121.7
}
}
}
}
}
GET /hotel/_search
{
"query": {
"geo_distance": {
"distance": "20km",
"location": {
"lat": 31.13,
"lon": 121.8
}
}
}
}
4、function score (算分控制)
復(fù)合查詢(compound ):將簡單查詢條件組合在一起,實(shí)現(xiàn)復(fù)雜搜索邏輯。
-
function score:算分函數(shù)查詢
,可以控制文檔的相關(guān)性算分,控制排名。例如百度競價(jià)
es在5.1及之后就棄用了 TF-IDF 算法,開始采用 BM25算法。BM25算法不會(huì)因?yàn)樵~的出現(xiàn)頻率變大而導(dǎo)致算分無限增大,會(huì)逐漸趨近一個(gè)值
function score query :可以修改文檔相關(guān)性算分,得到新的算分。
三要素
- 過濾條件:決定哪些條件要加分
- 算分函數(shù):如何計(jì)算function score
- 加權(quán)方式:function score 與 query score如何運(yùn)算
GET /hotel/_search
{
"query": {
"function_score": {
"query": {
"match": {
"all": "如家酒店"
}
},
"functions": [
{
"filter": {
"term": {
"city": "上海"
}
},
"weight": 10
}
],
"boost_mode": "sum"
}
}
}
5、bool 查詢
boolean query:布爾查詢是一個(gè)或多個(gè)子查詢的組合。
- must:必須匹配每個(gè)子查詢,類似”and“
- should:選擇性匹配子查詢,類似”or“
- must_not:必須不匹配,不參與算分,類似”非“
- filter:必須匹配,不參與算分
GET /hotel/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"all": "上海"
}
}
],
"must_not": [
{
"range": {
"price": {
"gt": 500
}
}
}
],
"filter": [
{
"geo_distance": {
"distance": "10km",
"location": {
"lat": 31.21,
"lon": 121.5
}
}
}
]
}
}
}
搜索結(jié)果處理
1、排序
es支持對搜索結(jié)構(gòu)進(jìn)行排序,默認(rèn)是根據(jù)相關(guān)度算分(_score)進(jìn)行排序??梢耘判虻淖侄斡衚eyword,數(shù)值、地理坐標(biāo)、日期類型等。
GET /hotel/_search
{
"query": {
"match_all": {}
},"sort": [
{
"id": {
"order": "desc"
}
}
]
}
GET /hotel/_search
{
"query": {
"match_all": {}
},"sort": [
{
"_geo_distance": {
"location": {
"lat": 31.2,
"lon": 121.5
},
"order": "asc",
"unit": "km"
}
}
]
}
這個(gè)排序的結(jié)果就是相聚的公里數(shù)。
2、分頁
針對深度分頁;ES給出了兩種方案
- search after:分頁時(shí)需要排序,原理是從上次的排序值開始(末尾值),查詢下一頁的數(shù)據(jù)。官方推薦使用,不會(huì)太占內(nèi)存。手機(jī)向下反動(dòng)滾頁。
- scroll:原理是將排序數(shù)據(jù)形成快照,保存在內(nèi)存。不推薦
3、高亮
ES默認(rèn)搜索字段和高亮字段必須一致,否則不會(huì)高亮?;蛘呤褂?"require_field_match": "false"
也能高亮。
最后將查詢結(jié)果中 highlight 與 指定高亮的字段進(jìn)行替換返回給前端就行。
RestClient操作
普通查詢
@Test
public void testMatchAll() throws IOException {
SearchRequest searchRequest = new SearchRequest("hotel");
searchRequest.source().query(
QueryBuilders.matchAllQuery()
);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
SearchHits searchHits = searchResponse.getHits();
long value = searchHits.getTotalHits().value;
System.out.println(value);
SearchHit[] hits = searchHits.getHits();
System.out.println(hits[0]);
HotelDoc hotelDoc = JSON.parseObject(hits[0].getSourceAsString(), HotelDoc.class);
System.out.println(hotelDoc);
}
QueryBuilders.matchAllQuery()
QueryBuilders.matchQuery("all","如家")
QueryBuilders.multiMatchQuery("如家","name","brand","business")
QueryBuilders.termQuery("city","上海")
QueryBuilders.rangeQuery("price").gt(100).lt(400)
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(QueryBuilders.termQuery("city","北京"));
boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gt(100).lt(400));
分頁和排序
public void testPageAndSort() throws IOException {
int pageNum = 2, pageSize = 10;
SearchRequest searchRequest = new SearchRequest("hotel");
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("brand", "如家");
MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("all", "北京");
boolQueryBuilder.must(termQueryBuilder);
boolQueryBuilder.must(matchQueryBuilder);
searchRequest.source().query(boolQueryBuilder);
searchRequest.source().from((pageNum - 1) * pageSize).size(pageSize);
searchRequest.source().sort("price", SortOrder.ASC);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
SearchHit[] hits = searchResponse.getHits().getHits();
for (SearchHit hit : hits) {
String source = hit.getSourceAsString();
HotelDoc hotelDoc = JSON.parseObject(source, HotelDoc.class);
System.out.println(hotelDoc);
}
}
高亮文章來源:http://www.zghlxwxcb.cn/news/detail-659969.html
public void testHighLight() throws IOException {
SearchRequest searchRequest = new SearchRequest("hotel");
searchRequest.source().query(QueryBuilders.matchQuery("all","如家"));
searchRequest.source().highlighter(new HighlightBuilder().field("name").requireFieldMatch(false));
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
SearchHit[] hits = searchResponse.getHits().getHits();
for (SearchHit hit : hits) {
String source = hit.getSourceAsString();
HotelDoc hotelDoc = JSON.parseObject(source, HotelDoc.class);
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
if(!highlightFields.isEmpty()){
HighlightField highlightField = highlightFields.get("name");
//一般value只有一個(gè)元素,取數(shù)組第一個(gè)
String name = highlightField.getFragments()[0].string();
hotelDoc.setName(name);
}
System.out.println(hotelDoc);
}
}
算分
讓指定酒店置頂 (function_score )廣告業(yè)務(wù)文章來源地址http://www.zghlxwxcb.cn/news/detail-659969.html
// 算分控制
FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.functionScoreQuery(
// 原始查詢
boolQueryBuilder,
// FunctionScore 數(shù)組
new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{
new FunctionScoreQueryBuilder.FilterFunctionBuilder(
QueryBuilders.termQuery("isAD", true),
ScoreFunctionBuilders.weightFactorFunction(10)
)
}
);
到了這里,關(guān)于ElasticSearch DSL語句(bool查詢、算分控制、地理查詢、排序、分頁、高亮等)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!