lucene join解決父子關係索引

2022-07-03 12:09:10 字數 3989 閱讀 4984

以商家(poi)維度來展示各種服務(比如**(deal)、直連)正變得越來越流行(圖1a), 比如目前美食、酒店等品類在移動端將**資訊列表改為poi列表頁展示。

圖1   a:商家維度展示資訊; b:join示意    

篩選在我們應用中,乙個poi儲存為乙個document,乙個deal也儲存為乙個document,join的核心在於將poi以及deal的document進行關聯。lucene提供了兩種join的方式,分別是query time join和index time join,下文將分別展開。

a)索引

public static document createpoidocument(poimsg poimsg)

public static document createdealdocument(dealmodel dealmodel, poimsg poimsg)

indexwriter writer = new indexwriter(directory, config);

writer.adddocument(createpoidocument(poimsg1));

writer.adddocument(createpoidocument(poimsg2));

writer.adddocument(createdealdocument(dealmodel1, poimsg2));

writer.adddocument(createdealdocument(dealmodel2, poimsg1));

writer.adddocument(createdealdocument(dealmodel3, poimsg1));

b)查詢1)第一次查詢發生在joinutil.createjoinquery中。首先建立了termscollector這個收集器, 該收集器將滿足fromquery的doc的parentid欄位收集起來,之後建立了termsquery。

2)執行termsquery,查詢tofield在termscollector terms集合中存在的doc,最後找出tofield為「1」的doc。

indexsearcher indexsearcher = new indexsearcher(indexreader);

string fromfields = "parentid";

query fromquery = numericrangequery.newintrange("price", 100, 200, false, false);

string tofields = "poiid";

query toquery = joinutil.createjoinquery(fromfields, false, tofields, fromquery, indexsearcher, scoremode.max);

topdocs results = indexsearcher.search(toquery, 10);

joinutil.createjoinquery**

termscollector termscollector = termscollector.create(fromfield, multiplevaluesperdocument);

fromsearcher.search(fromquery, termscollector);

return new termsquery(tofield, fromquery, termscollector.getcollectorterms());

c)優缺點a)原理

圖2 lucene自己實現了bitset來儲存id,lucene內部實現**如圖3所示。

圖3 實現原理

b)索引

public static document createpoidocument(poimsg poimsg)

public static document createdealdocument(dealmodel dealmodel)

indexwriter writer = new indexwriter(directory, config);

listdocuments = new arraylist();

documents.add(createdealdocument(dealmodel2));

documents.add(createdealdocument(dealmodel3));

documents.add(createpoidocument(poimsg1));

writer.adddocument(documents);

documents.clear();

documents.add(createdealdocument(dealmodel1));

documents.add(createpoidocument(poimsg2));

writer.adddocument(documents);

c)查詢toparentblockjoinquery query = new toparentblockjoinquery(dealquery, poifilter, scoremode.max);

toparentblockjoincollector collector = new toparentblockjoincollector(

sort, // sort

(getoffset() + getlimit()), // poi分頁numhits

true, // trackscores

false // trackmaxscore

);collector = (toparentblockjoincollector) indexsearcher.search(query, collector);

sort childsort = new sort(new sortfield(deallucenefield.attr_price, sortfield.type.double));

topgroups hits = collector.gettopgroups(

query.gettoparentblockjoinquery(),

childsort,

query.getoffset(), // parent doc offset

100, // maxdocspergroup

0, // withingroupoffset

true // fillsortfields

);官方文件顯示index time join效率更高,比query time join快30%以上。因此我們在專案中使用了index time join方式,目前服務執行良好。

lucene字典實現原理

lucene索引檔案大小優化小結

排序學習實踐

lucene如何通過docid快速查詢field欄位以及最近距離等資訊?

使用Jest客服端建立 parent父子關係

注意 請在索引庫沒有資料的時候建立父子關係,子對映必須先建立 第一步 建立索引庫 task為任務型別,processins為流程例項,乙個流程例項包含多個流程任務。注意 task和processins其它屬性不用專門建立對映,elasticsearch會為我們主動建立 第三步 新增索引資料 proc...

關與inflate的雜談為了解決我上個部落格的問題

先說 activity 的setcontextview view view 追蹤原始碼最後可以看到是呼叫了 phonewindow 物件的setcontextview view view 可以看到不管設定的view是否有parent,都會重新設定乙個matchparent 的 layoutparam...

開啟CMD一閃就關的解決方案

url 個人使用方法2,問題已解決 方法1 你中毒了,系統中有個程序在監測你的命令,看到cmd就關閉,可以在任務管理中看看有沒有可以程序,關掉他,應該可以開啟,如果還不行,那就是已經注入系統程序。防毒就很困難了。重做系統好一點。方法2 登錄檔 hkey local machine software ...