2011-07-02 26 views
6

我有一组文档,每个文档都包含一个子文档数组。每个子文档都有一个时间值。我正在尝试查看是否可以根据子文档中的时间返回子文档。MongoDB查询通过数组中的值检索一个数组值

我知道我可以使用$ slice检索子文档,但$ slice只给我一个特定的索引或范围和偏移量。

示例时间!

文件是像这样....

{ 
    id: 1234, 
    type: 'a', 
    subs: [ 
     { time: 123001, val: 'a' }, 
     { time: 123002, val: 'b' }, 
     { time: 123003, val: 'c' } 
    ] 
} 

如果我做查找查询({},{替补:{$切片:[2,1]}})我回来像:

{ id: 1234, type: 'a', subs: [{ time: 123002, val: 'b' }]} 

我想检索该记录,例如基于没有偏移量,但基于123002时间值。

可能吗?

去吧!

回答

4

正如你设计的数据这是不可能的。

在MongoDB中,查询返回整个文档。您可以过滤特定的字段,但是如果字段的值是一个数组,则它停在那里。

当您有“对象数组”时,您必须$slice,这不是您想要的,或者您必须以不同方式对数据建模。

在你的情况,下面的结构会让你的查询可能:

{ 
    _id: 1234, 
    type: 'a', 
    subs: { 
     '123001': { val: 'a' }, 
     '123002': { val: 'b' }, 
     '123003': { val: 'c' } 
    } 
} 

注意我是如何改变subs成JSON对象而不是数组。现在,你可以做以下查询,得到的只是你正在寻找的时间:

find({ _id: 1234 }, { 'subs.123002': 1 }) 

这里最明显的权衡是,你将不得不改变你使用更改文档的方式。您不能在subs上使用$push,您无法查询{'subs.time': 1234},而是必须查询{'subs.1234': { $exists:true} }

+0

哦,呵呵!是的,这将工作。谢谢。虽然除非我误解你在说什么,你可以返回一个文档的一部分.. http://www.mongodb.org/display/DOCS/Retrieving+a+Subset+of+Fields只是不使用片的数组的一部分。谢谢! – FredArters

+0

如果你使用你的原始结构,你可以做'subs.2'来获得数组中的第三个元素。但是你通常不知道第三项是什么。所以对于数组来说,它通常是全或全无。 –

+1

问题是旧的,但也许这对寻找答案的人有用。可以使用$ elemMatch将数组中的一个文档进行匹配。 http://www.mongodb.org/display/DOCS/Dot+Notation+%28Reaching+into+Objects%29#DotNotation%28ReachingintoObjects%29-Matchingwith%24elemMatch – Esteban