2012-01-29 160 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