elastic 比較mapping裡邊2個變數的大小
阿新 • • 發佈:2019-01-01
一:傳統方式可以用指令碼
GET /_search { "query": { "bool" : { "must" : { "script" : { "script" : { "inline": "doc['field1'].value > doc['field2'].value", "lang": "painless" } } } } } }
Script Queryedit
A query allowing to define scripts as queries. They are typically used in a filter context, for example:
GET /_search { "query": { "bool" : { "filter" : { "script" : { "script" : { "source": "doc['num1'].value > 1", "lang": "painless" } } } } } }
Custom Parametersedit
Scripts are compiled and cached for faster execution. If the same script can be used, just with different parameters provider, it is preferable to use the ability to pass parameters to the script itself, for example:
GET /_search { "query": { "bool" : { "filter" : { "script" : { "script" : { "source" : "doc['num1'].value > params.param1", "lang" : "painless", "params" : { "param1" : 5 } } } } } } }
java api 的構建
public static BoolQueryBuilder buildTodayFormalClosedCountBuilder(StatisticsRequest request) {
BoolQueryBuilder boolQueryBuilder = buildConditionQuery(request);
boolQueryBuilder.filter(QueryBuilders.termQuery(CaseDbEsRelEnum.STATUS_ID.getEsName(), 2));
boolQueryBuilder.filter(QueryBuilders.scriptQuery(new Script("doc['closeTime'].value < doc['deadline'].value")));
boolQueryBuilder.filter(QueryBuilders.termQuery(CaseDbEsRelEnum.TIMEOUT_CLOSE_FLAG.getEsName(), 0));
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.add(Calendar.DATE, 0);
boolQueryBuilder.filter(QueryBuilders.rangeQuery(CaseDbEsRelEnum.CLOSE_TIME.getEsName()).gt(calendar.getTime()));
return boolQueryBuilder;
}
二:其實可以用一個變數標誌來代替指令碼的,因為指令碼相對比較耗時
比如在過濾中 addtime < closetime
可以在 通過接受dababus的變更通過kafka發出來的訊息,對eslastic 進行資料寫入的時候,增加一個變數比較2個變數,來對一個新的falg 標誌變數進行賦值。
最好是在索引階段就單獨索引一個欄位,用來存放2個field大小比較的結果,比如欄位名稱為 field1_lg_field2, 可以存放1/0用於表示那個欄位大, 這樣在搜尋過濾的時候速度比使用script臨時計算要快得多。
ES搜尋的最佳實踐是將開銷都放在資料索引階段,搜尋階段儘量用最簡單的查詢,這是提升查詢效率的關鍵。