多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > php教程 > Elasticsearch nested sort filter 嵌套排序問題及解決

Elasticsearch nested sort filter 嵌套排序問題及解決

來源:程序員人生   發布時間:2016-04-14 09:24:09 閱讀次數:11747次

官方解釋

首先來看1下官方文檔:Sorting by Nested Fields
看不懂的沒關系,它其實就只有兩句是有用的,就是那兩段代碼。

索引

PUT /my_index/blogpost/2 { "title": "Investment secrets", "body": "What they dont tell you ...", "tags": [ "shares", "equities" ], "comments": [ { "name": "Mary Brown", "comment": "Lies, lies, lies", "age": 42, "stars": 1, "date": "2014⑴0⑴8" }, { "name": "John Smith", "comment": "Youre making it up!", "age": 28, "stars": 2, "date": "2014⑴0⑴6" } ] }

嵌套查詢

GET /_search { "query": { "nested": { "path": "comments", "filter": { "range": { "comments.date": { "gte": "2014⑴0-01", "lt": "2014⑴1-01" } } } } }, "sort": { "comments.stars": { "order": "asc", "mode": "min", "nested_filter": { "range": { "comments.date": { "gte": "2014⑴0-01", "lt": "2014⑴1-01" } } } } } }

以上是官方代碼,方便打不開網頁的同學查看。下面是我遇到的問題及解決方法。

記錄

這里只提供了RestfulAPI,我在使用java的進程中遇到了很多問題。有超過1半的時間都耗在這里了,特此記錄1下。

問題

項目中使用java API,所以參照ResefulAPI寫出來1段代碼。
首先是有1段正確的restful 代碼,這1段是仿照官方文檔寫的,運行后測試正確無誤。

{ "sort": { "goods_sale_number.sale_num": { "order": "asc", "nested_filter": { "term": { "warehouse_id": "22" } }, "missing": "_last" } }, "size": "99999", "_source": [ "goods_sale_number", "id" ] }

毛病的java代碼,根據json轉換的,運行后沒法排序。

String flag = sortOrder.toString().equals("desc") ? "_last" : "_first"; FilterBuilder termFilter = FilterBuilders.termFilter("goods.goods_sale_number.warehouse_id", warehouseId); searchRequestBuilder.addSort(SortBuilders.fieldSort("goods_sale_number.sale_num") .setNestedFilter(FilterBuilders.nestedFilter("goods_sale_number", termFilter)) .setNestedPath("goods.goods_sale_number") .order(sortOrder).missing(flag));

乍1看,其實java代碼和restful的代碼并沒有甚么區分,但是卻1直不能使用。

分析及解決問題

  1. 我嘗試過各種各樣的寫法,改變訪問的路徑,切換過濾的類型,能試過的方法都試過了,但是還是不可以正確排序。
  2. 由于SearchRequestBuilder類有1個方法可以直接setSource(String),固然,它只能單獨使用。如果還有其它的參數,可使用searchRequestBuilder.setExtraSource(String)。所以我嘗試把json的值放在這個函數里面使用,結果是正確的,正序逆序都是正確的。
  3. 猜想:多是轉換的進程中出錯了。(由于elasticsearch 是基于lucene的,所以我猜想是json轉換java的結果可能和我寫的不1樣。實際在查看代碼后發現實際上是把java代碼轉換成了json,放在了searchRequestBuilder.source里面

elasticsearch源碼分析

源碼

package org.elasticsearch.action.search; public class SearchRequestBuilder extends ActionRequestBuilder<SearchRequest, SearchResponse, SearchRequestBuilder, Client> { ... //這個方法就是解決問題的本源 public SearchRequest request() { if(this.sourceBuilder != null) { ((SearchRequest)this.request).source(this.sourceBuilder()); } return (SearchRequest)this.request; } ... }

分析

在此我們可以看到有1個this.sourceBuilder(),它里面的值,就是我們寫的java代碼,query,filter,sort 等等都會在這里轉換成json,寫入到searchRequestBuilder.source,而searchRequestBuilder.extraSource則是之前我寫入的另外一部份json,得到這兩部份值后對照1下。

//source "sort" : [ { "goods_sale_number.sale_num" : { "order" : "desc", "missing" : "_last", "nested_filter" : { "nested" : { "filter" : { "term" : { "goods.goods_sale_number.warehouse_id" : "22" } }, "path" : "goods_sale_number" } }, "nested_path" : "goods.goods_sale_number" } } ]
//extraSource "sort": { "goods_sale_number.sale_num": { "order": "asc", "nested_filter": { "term": { "warehouse_id": "22" } }, "missing": "_last" } }

可以看到有明顯的不同,不同就在于,中間多了幾個nested的嵌套。所以分析出多是由于對英文文檔理解不當,sort里面的查詢并不是是嵌套查詢,只是1個普通的查詢。由于它本身在添加排序的時候就已是嵌套了。

修改后的java代碼:

String flag = sortOrder.toString().equals("desc") ? "_last" : "_first"; FilterBuilder termFilter = FilterBuilders.termFilter("warehouse_id", warehouseId); searchRequestBuilder.addSort(SortBuilders.fieldSort("goods_sale_number.sale_num") .setNestedFilter(termFilter) .order(sortOrder).missing(flag));

再次分析json:

//source "sort" : [ { "goods_sale_number.sale_num" : { "order" : "desc", "missing" : "_last", "nested_filter" : { "term" : { "warehouse_id" : "22" } } } } ]

這1次的值和restful API 的json1模1樣了。再次履行后發現正確無誤。

終究正確的代碼

正確的java代碼

String flag = sortOrder.toString().equals("desc") ? "_last" : "_first"; FilterBuilder termFilter = FilterBuilders.termFilter("warehouse_id", warehouseId); searchRequestBuilder.addSort(SortBuilders.fieldSort("goods_sale_number.sale_num") .setNestedFilter(termFilter) .order(sortOrder).missing(flag));

問題總結

  1. 把英文學好
  2. 遇到問題打斷點
  3. 看源碼
  4. 要有耐心
  5. 要仔細

其間遇到的其它問題(child query must only match non-parent docs)

1個毛病日志

[2015-10-20 18:15:25,553][DEBUG][action.search.type ] [local] [shop][4], node[uv2Ii94-R8a_Wk00s7bPew], [P], s[STARTED]: Failed to execute [org.elasticsearch.action.search.SearchRequest@1ba36675] org.elasticsearch.search.query.QueryPhaseExecutionException: [shop][4]: query[ConstantScore(cache(+_type:goods +org.elasticsearch.index.search.nested.NonNestedDocsFilter@5005b052))],from[0],size[10],sort["goods_sale_number.sale_num": org.elasticsearch.index.fielddata.fieldcomparator.LongValuesComparatorSource@31026d4e>!]: Query Failed [Failed to execute main query] at org.elasticsearch.search.query.QueryPhase.execute(QueryPhase.java:163) at org.elasticsearch.search.SearchService.loadOrExecuteQueryPhase(SearchService.java:289) at org.elasticsearch.search.SearchService.executeQueryPhase(SearchService.java:300) at org.elasticsearch.search.action.SearchServiceTransportAction$5.call(SearchServiceTransportAction.java:231) at org.elasticsearch.search.action.SearchServiceTransportAction$5.call(SearchServiceTransportAction.java:228) at org.elasticsearch.search.action.SearchServiceTransportAction$23.run(SearchServiceTransportAction.java:559) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:745) Caused by: org.elasticsearch.common.util.concurrent.UncheckedExecutionException: java.lang.IllegalStateException: child query must only match non-parent docs, but parent docID=1 matched childScorer=class org.apache.lucene.search.ConstantScoreQuery$ConstantScorer at org.elasticsearch.common.cache.LocalCache$Segment.get(LocalCache.java:2203) at org.elasticsearch.common.cache.LocalCache.get(LocalCache.java:3937) at org.elasticsearch.common.cache.LocalCache$LocalManualCache.get(LocalCache.java:4739) at org.elasticsearch.index.cache.fixedbitset.FixedBitSetFilterCache.getAndLoadIfNotPresent(FixedBitSetFilterCache.java:136) at org.elasticsearch.index.cache.fixedbitset.FixedBitSetFilterCache.access$100(FixedBitSetFilterCache.java:73) at org.elasticsearch.index.cache.fixedbitset.FixedBitSetFilterCache$FixedBitSetFilterWrapper.getDocIdSet(FixedBitSetFilterCache.java:218) at org.elasticsearch.index.fielddata.IndexFieldData$XFieldComparatorSource$Nested.innerDocs(IndexFieldData.java:150) at org.elasticsearch.index.fielddata.fieldcomparator.LongValuesComparatorSource$1.getLongValues(LongValuesComparatorSource.java:73) at org.apache.lucene.search.FieldComparator$LongComparator.setNextReader(FieldComparator.java:716) at org.apache.lucene.search.TopFieldCollector$OneComparatorNonScoringCollector.setNextReader(TopFieldCollector.java:97) at org.elasticsearch.common.lucene.MultiCollector.setNextReader(MultiCollector.java:66) at org.apache.lucene.search.IndexSearcher.search(IndexSearcher.java:612) at org.elasticsearch.search.internal.ContextIndexSearcher.search(ContextIndexSearcher.java:191) at org.apache.lucene.search.IndexSearcher.search(IndexSearcher.java:581) at org.apache.lucene.search.IndexSearcher.search(IndexSearcher.java:533) at org.apache.lucene.search.IndexSearcher.search(IndexSearcher.java:510) at org.apache.lucene.search.IndexSearcher.search(IndexSearcher.java:345) at org.elasticsearch.search.query.QueryPhase.execute(QueryPhase.java:150) ... 8 more Caused by: java.lang.IllegalStateException: child query must only match non-parent docs, but parent docID=1 matched childScorer=class org.apache.lucene.search.ConstantScoreQuery$ConstantScorer at org.apache.lucene.search.join.ToParentBlockJoinQuery$BlockJoinScorer.nextDoc(ToParentBlockJoinQuery.java:286) at org.elasticsearch.index.cache.fixedbitset.FixedBitSetFilterCache$2.call(FixedBitSetFilterCache.java:148) at org.elasticsearch.index.cache.fixedbitset.FixedBitSetFilterCache$2.call(FixedBitSetFilterCache.java:136) at org.elasticsearch.common.cache.LocalCache$LocalManualCache$1.load(LocalCache.java:4742) at org.elasticsearch.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3527) at org.elasticsearch.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2319) at org.elasticsearch.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2282) at org.elasticsearch.common.cache.LocalCache$Segment.get(LocalCache.java:2197) ... 25 more

毛病緣由

當前嵌套的字段不在父級下面。
也就是,有1個shop索引(index),它有goods類型(type),然后它的屬性(properties)里面有1個嵌套類型字段 sale_number (nested),它有兩個字段叫 sale_number和 id,此時如果你使用sale_number.sale_number去訪問這個字段是訪問不到的,需要使用goods.sale_number.sale_number,所以加上前面的type就能夠了。但是這是在代碼毛病的時候遇到的毛病的問題,僅此記錄,它其實不能在實際使用中常常遇到。

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 午夜福利毛片 | 中文字幕在线视频网站 | 九九精品视频一区二区三区 | 久久精品免费全国观看国产 | 欧美精品v欧洲精品 | 日本在线观看一区二区三区 | 波多野吉衣在线多野结衣 | 就操网| 欧美一级毛片欧美一级成人毛片 | 在线综合亚洲欧美网站天堂 | 精品视频久久久久 | 免费观看欧美性一级 | 一级做a免费视频 | 久久一区二区三区精品 | 激情综合亚洲欧美日韩 | 蜜中蜜3动漫无修在线播放 免费 黄 色 人成 视频 | 成人欧美视频在线观看播放 | 欧美xxxx网站 | 美国一级淫片 | 国产精品亚洲综合第一区 | 亚洲最大成人在线 | 欧美色综合久久 | 欧美一区二区另类有声小说 | 在线 v亚洲 v欧美v 专区 | 午夜视频在线网站 | 亚洲国产精品第一区二区 | 国内自拍视频在线看免费观看 | 日本护士xxxx黑人巨大 | 校园春色 激情 | 日本高清一道本 | 国产日韩欧美一区二区三区视频 | 亚洲另类春色小说 | 国产91成人精品亚洲精品 | 国产在线精品福利一区二区三区 | 国产精品11页| 伊人网99 | 精品无码中出一区二区 | 成年人视频免费网站 | 国产亚洲福利 | 久久久精品国产免费观看同学 | 国产综合免费视频 |