2012-01-29 156 views
0

我想知道如何在MongoDB中實現位置倒排索引。通過使用多鍵功能,可以創建倒排索引,但是如何以有效的方式存儲出現位置呢?MongoDB中的位置倒排索引

比方說,我們有這個對象

obj = { 
    name: "Apollo", 
    text: "Some text about Apollo moon landings", 
    keywords: [ "some", "text", "about", "apollo", "moon", "landings" ] 
} 

我就知道希望能夠進行查詢,其中「阿波羅」和「着陸」將不得不進行連接,而不僅僅是做一個「交集」查詢。

回答

1

什麼對象,如:

obj = { 
    name: "Apollo", 
    text: "Some text about Apollo moon landings", 
    keywords: [ 
    {idx:0, text: "some"}, 
    {idx:1, text: "text"}, 
    {idx:2, text: "about"}, 
    {idx:3, text: "apollo"}, 
    {idx:4, text: "moon"}, 
    {idx:5, text: "landings"} 
    ] 
} 

你可以做一個ensureIndex的「keywords.text」做一個查詢,其中這兩個關鍵字的存在,然後使用JavaScript的「裏」過濾器檢查的相對位置的輸入關鍵字。

1

您可以使用$和或$ all操作符來完成我相信您期望完成的操作。

鑑於你的示例文檔:

> db.test.find().pretty() 
{ 
    "_id" : ObjectId("4f26b716c27b085280a45a29"), 
    "name" : "Apollo", 
    "text" : "Some text about Apollo moon landings", 
    "keywords" : [ 
     "some", 
     "text", 
     "about", 
     "apollo", 
     "moon", 
     "landings" 
    ] 
} 

你可以用$和運營商尋找他的「關鍵詞」數組包含兩個單詞的文檔。

> db.test.find({$and:[{keywords:"apollo"}, {keywords:"landings"}]}) 
{ "_id" : ObjectId("4f26b716c27b085280a45a29"), "name" : "Apollo", "text" : "Some text about Apollo moon landings", "keywords" : [ "some", "text", "about", "apollo", "moon", "landings" ] } 
> 

的$所有操作員將返回相同的結果,並且查詢是多一點精簡:

> db.test.find({keywords:{$all:["apollo", "landings"]}}) 
{ "_id" : ObjectId("4f26b716c27b085280a45a29"), "name" : "Apollo", "text" : "Some text about Apollo moon landings", "keywords" : [ "some", "text", "about", "apollo", "moon", "landings" ] } 

如果我們把索引關鍵字陣列上,這兩個查詢使用它。

> db.test.ensureIndex({keywords:1}) 
> db.test.find({$and:[{keywords:"apollo"}, {keywords:"landings"}]}).explain() 
{ 
    "cursor" : "BtreeCursor keywords_1", 
    "nscanned" : 1, 
    "nscannedObjects" : 1, 
    "n" : 1, 
    "millis" : 0, 
    "nYields" : 0, 
    "nChunkSkips" : 0, 
    "isMultiKey" : true, 
    "indexOnly" : false, 
    "indexBounds" : { 
     "keywords" : [ 
      [ 
       "apollo", 
       "apollo" 
      ] 
     ] 
    } 
} 
> db.test.find({keywords:{$all:["apollo", "landings"]}}).explain() 
{ 
    "cursor" : "BtreeCursor keywords_1", 
    "nscanned" : 1, 
    "nscannedObjects" : 1, 
    "n" : 1, 
    "millis" : 0, 
    "nYields" : 0, 
    "nChunkSkips" : 0, 
    "isMultiKey" : true, 
    "indexOnly" : false, 
    "indexBounds" : { 
     "keywords" : [ 
      [ 
       "apollo", 
       "apollo" 
      ] 
     ] 
    } 
} 
> 

這兩個查詢都使用關鍵字索引。

有關不同類型查詢的更多信息,請參閱「高級查詢」文檔。
http://www.mongodb.org/display/DOCS/Advanced+Queries

有關Mongo索引如何工作的更多信息,請參閱「索引」文檔。
http://www.mongodb.org/display/DOCS/Indexes#Indexes-IndexingArrayElements

「索引數組元素」部分鏈接到MultiKeys上的文檔。 http://www.mongodb.org/display/DOCS/Multikeys

如果你不熟悉的MongoDB的.explain功能,在這裏解釋: http://www.mongodb.org/display/DOCS/Explain 簡而言之,它會顯示你的查詢使用任何索引,多少需要的文件,以進行訪問返回相關的。

最後,你的問題看起來與另一個用戶在今天早些時候詢問有關在數組中搜索值有什麼相似之處。也許這也與你有關。
http://groups.google.com/group/mongodb-user/browse_thread/thread/38f30a56094d9e3e

希望這可以幫助您編寫您正在查找的查詢。如果您有任何後續問題,請告訴我們!

+0

我的問題可能寫得很差,但是我想解決的問題是查詢應該只返回「apollo」和「landing」彼此相鄰的結果,例如在短語查詢「apollo landingings」 。如果我有一個帶有「apollo xxxx着陸」的文本,查詢不應該返回它,因爲它不是一個短語。是否有可能做出這樣的查詢? – freakshow 2012-01-30 19:02:07