官术网_书友最值得收藏!

3.3.15 關(guān)聯(lián)內(nèi)容(BlockJoinQuery)

一個簡單的例子:假如有個網(wǎng)店賣襯衫,每件襯衫有一些常見的字段,如名稱、描述、織物、價格等。對于每件襯衫,有許多單獨的庫存單元,它具有自己的列,如大小、顏色、庫存數(shù)量等。庫存單元叫作SKU。這些型號是你實際出售的,或在你的庫存中,因為當(dāng)有人買襯衫時,他們買的是特定的SKU產(chǎn)品(大小和顏色)。

也許你賣的是袋鼠牌短袖T恤,有下列SKU(大小,顏色):

● 小號,藍(lán)色

● 小號,黑色

● 中號,黑色

● 大號,灰色

可能用戶首先搜索“袋鼠 襯衫”,得到一個結(jié)果分支。然后下鉆到一個特定的型號和顏色。產(chǎn)生這個查詢:

        name:袋鼠AND size=小號AND color=藍(lán)色

這應(yīng)該匹配名稱是“襯衫”列,而大小和顏色是SKU列的襯衫。

但是,如果用戶下鉆到一個小號的灰色襯衫:

        name:袋鼠AND size=小號AND color=灰色

這件襯衫查詢不會返回任何結(jié)果,因為小號襯衫只有藍(lán)色和黑色。

如何使用BlockJoinQuery運行這個查詢?從把每件襯衫(父親)和它所有的SKU(孩子)當(dāng)作獨立的文檔索引開始。

使用新的IndexWriter.addDocuments API增加一件T恤和它所有的SKU作為一個獨立的文檔塊。這個方法自動增加一個文檔塊成為一個有相鄰的文檔編號的獨立的段。這是BlockJoinQuery起作用的基礎(chǔ)。

也要加一個標(biāo)志列到每個襯衫文檔,例如,type = shirt。因為BlockJoinQuery需要一個Filter標(biāo)識出父文檔。

要在搜索階段運行BlockJoinQuery,首先要創(chuàng)建一個父過濾器匹配T恤。注意,過濾器在底層必須使用FixedBitSet,就像CachingWrapperFilter:

        Filter shirts = new CachingWrapperFilter(
                          new QueryWrapperFilter(
                            new TermQuery(
                            new Term("type", "shirt"))));

一旦創(chuàng)建好這個過濾器,任何時間需要執(zhí)行Join的時候,都可以重用這個過濾器。

然后每個查詢都需要join,因為涉及SKU和襯衫列。從孩子查詢開始,只匹配SKU字段:

        BooleanQuery skuQuery = new BooleanQuery();
        skuQuery.add(new TermQuery(new Term("size", "small")), Occur.MUST);
        skuQuery.add(new TermQuery(new Term("color", "blue")), Occur.MUST);

接下來,使用BlockJoinQuery轉(zhuǎn)換命中結(jié)果,把它們從SKU文檔空間上升到襯衫文檔空間:

        BlockJoinQuery skuJoinQuery = new BlockJoinQuery(
            skuQuery,
            shirts,
            ScoreMode.None);

這里的ScoreMode enum類型決定應(yīng)該如何為多個SKU命中結(jié)果打分。在這個查詢中,不需要SKU匹配出來的分?jǐn)?shù),但是如果需要的話,可以用平均數(shù)、最大值或者求和的方法打分。

最后,可以使用skuJoinQuery作為子句,構(gòu)建任意的襯衫查詢:

        BooleanQuery query = new BooleanQuery();
        query.add(new TermQuery(new Term("name", "wolf")), Occur.MUST);
        query.add(skuJoinQuery, Occur.MUST);

這個連接是一對多(父親對孩子)的內(nèi)連接。

主站蜘蛛池模板: 泗阳县| 五台县| 澳门| 沈丘县| 德兴市| 新巴尔虎右旗| 五寨县| 邢台市| 乡宁县| 文安县| 昌都县| 宜川县| 揭西县| 郴州市| 陵川县| 陆良县| 泰兴市| 曲周县| 烟台市| 扎鲁特旗| 龙门县| 西丰县| 高州市| 澎湖县| 梁河县| 韶山市| 梅州市| 南川市| 鹤庆县| 曲松县| 富阳市| 青川县| 桓台县| 屏东县| 大足县| 明水县| 渭南市| 郎溪县| 冀州市| 乐山市| 吉木乃县|