2011-01-29 167 views
0

我正在使用MongoDB来存储一堆信息,并且需要搜索索引数组的值。MongoDB数组索引搜索

这里的模式:

{ "common_name" : { "name" : "thename", "type" : "thetype" } } 

有文档中的其他值,但是这是唯一一个我在寻找。

所以,我估计像这样的工作:(中壳)

db.collection.find({common_name:{$in:"thename"}}) 

但我得不到任何回报。

这看起来就像这里所做的一样: http://www.php.net/manual/en/mongo.queries.php - 但我似乎无法得到任何回报。

我已经试过

db.collection.find({"common_name.name":"thename"}}) 

和它的作品如预期,但对指数(最多4个)搜索多个节点,它可能会变得非常恶劣,基本定义$或索引的每个子类,和四倍我的查询时间。因为这是一个自动补全的动力,我不能那样做。

奇怪的是,以下不返回任何证件之一:

db.collection.find({"common_name":{"name":"thename"}}) 

这在我的理解,是完全一样的东西上面的查询。

我对Mongo很新,所以也许我在这里错过了一些大东西?

有关如何快速访问这些数据(使用锚定正则表达式)的任何想法?

我可以只使用一个关系表,但是不会破坏像Mongo这样的NoSQL系统的目的吗?

回答

2

问题是你没有数组。一个数组看起来像{ "common_name" : [ "name1", "name2", "name3" ] }

使用这样的结构,Mongo可以将数组的元素索引到单个索引中,并快速找到包含数组中任何单个项目的任何文档。

可能使用一个数组,并简单地定义偏移量是你想要的,例如, [0]是名称,[1]是类型等等。有了这个功能,您现在可以快速找到任何文档。

可以做到这一点除了以保持数据的命名字段(但很明显,这将增加存储所以不推荐)。

如果您的自动完成功能不需要将最新的文档添加到集合中即可完全更新,您可以运行map-reduce作业来构建您仅用于自动完成的单独集合。地图步骤将为文档中的每个单独的名称字段发出(因此排出后的文档数量是文档的4倍),减少步骤将计算每个名称的数量(因此,所有字段中的唯一名称数量是1x) 。您可以通过名称和计数索引产生的集合,这将允许您的自动完成功能首先推荐最常用的名称。

+0

啊,我担心这可能是问题所在。我会改变我的模式以这种方式工作。要么我误解了这里的PHP文档http://www.php.net/manual/en/mongo.queries.php,或者他们是不正确的。谢谢! – Jesse 2011-01-29 21:00:04

0

db.collection.find({"common_name":{"name":"thename"}})对我来说,这和上面的查询完全一样。

不,这不是因为这将只匹配如果common_name值将只是name: thename},你想要的$elemMatch操作。