2011-10-29 42 views
4

我需要爲某些數據集創建一個匹配取景器系統,具體如下:多參數匹配取景器與Redis的

有一組對象,每個識別出的由一個字符串ObjectID

每個對象都有N個屬性P i。每個屬性值都是一個字符串。

N = 3(實際生活中N = 8)的數據庫示例。

 
ObjectID: P1  P2 P3 
-------------------------------- 
APPLE: RED ROUND FRUIT 
ORANGE: ORANGE ROUND FRUIT 
CARROT: RED LONG VEGETABLE 

該系統必須返回集合ObjectID s,匹配給定查詢對象屬性。在查詢中,用戶必須指定所有的屬性值。或者,對於查詢中的某些或全部屬性,用戶可以指定「通配符」,即任何屬性值都將與條件匹配。

查詢示例:

 
P1 P2 P3  => Result 
------------------------------------ 
* ROUND FRUIT  => APPLE, ORANGE 
RED LONG VEGETABLE => CARROT 
RED *  *   => CARROT, APPLE 

所有這一切都與SQL是平凡完成。

現在的問題是:是否有一個乾淨的方式與Redis做到這一點?

請注意,我對Redis解決方案感興趣,專門用於自我教育目的;其他數據庫對於這個特定的問題是偏離主題的。

更新:有明確ObjectID名單瑣碎的解決方案,每個P 和應用側濾波看起來不整潔對我來說夠:-)

+0

這是一個有趣的問題來回答。我期待着看到其他人能否想出更好的方法。我基本上做了「不重要的明確列表」,但在Redis方面做了過濾;)。我希望那已經夠整齊了。 –

回答

6

你正在嘗試做的,是一個倒指數。

對於每一列,讓它映射到一個「set」。然後,您可以交集這些集合以獲得結果。

所以,APPLE: RED ROUND FRUIT將映射到以下插入:

SADD p1:RED APPLE 
SADD p2:ROUND APPLE 
SADD p3:FRUIT APPLE 

然後,讓我們說我想查詢* ROUND FRUIT,我會做:

SINTER p2:ROUND p3:FRUIT 

此命令採取的交集p2:ROUND集合中的項目和p3:FRUIT集合中的項目。這將返回所有ROUNDFRUIT的項目,而不關注p1是什麼。

一些其他的例子:

SMEMBERS p1:GREEN 
SINTER p1:RED p2:ROUND p3:FRUIT 
SUNION p1:RED p1:GREEN 

我上面的回答是要使用一些計算能力,因爲交集操作O(N*M)。這是一種更加內存密集的方式,但是由於它有效地預先計算了索引,因此檢索速度會更快。

有關屬性的每個組合,使存儲一組關鍵:

所以,APPLE: RED ROUND FRUIT將映射到以下插入:

SADD RED:ROUND:FRUIT APPLE 
SADD :ROUND:FRUIT APPLE 
SADD RED::FRUIT APPLE 
SADD RED:ROUND: APPLE 
SADD RED:: APPLE 
SADD :ROUND: APPLE 
SADD ::FRUIT APPLE 
SADD ::: APPLE 

然後,查詢,只需訪問相應的鍵。例如,* ROUND FRUIT,簡直是

SMEMBERS :ROUND:FRUIT 

顯然,這不,當你有很多方面都很好地擴展在內存方面,但是這將是極其活潑的檢索結果。