通过数组中的值检索一个数组值的MongoDB查询

7

我有一组包含子文档数组的文档,每个子文档都有一个时间值。 我想看看是否可以根据子文档中的时间返回子文档。

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

例子时间!

文档如下....

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

如果我使用find({}, {subs: {$slice: [2,1]}})进行查询,那么我会得到类似以下的结果:
{ id: 1234, type: 'a', subs: [{ time: 123002, val: 'b' }]}

我希望可以根据时间戳123002来检索记录,而不是基于偏移量进行检索。

有可能吗?

开始吧!

1个回答

5
由于你设计的数据结构,这是不可能实现的。
在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} }


哦,嗯!那会起作用。谢谢你。不过,除非我误解了你的意思,你可以返回文档的一部分...http://www.mongodb.org/display/DOCS/Retrieving+a+Subset+of+Fields,只是不能使用slice返回数组的一部分。谢谢! - FredArters
如果您使用原始结构,可以使用'subs.2'来获取数组中的第三个元素。但是通常您不知道第三个元素到底是什么。因此对于数组来说,通常是全有或全无。 - Gates VP
1
虽然这个问题比较老,但是对于寻找答案的人来说可能还是有用的。可以使用$elemMatch将数组中的一个文档进行匹配。详情请参考:http://www.mongodb.org/display/DOCS/Dot+Notation+%28Reaching+into+Objects%29#DotNotation%28ReachingintoObjects%29-Matchingwith%24elemMatch - Esteban
$elemMatch并不完美。上次我使用它时,顺序很重要:{"$elemMatch": {shape: "square", color: "purple"}} != {"$elemMatch": {color: "purple", shape: "square"}}。这真的很糟糕,因为你无法控制那个顺序。 - Gates VP
@GatesVP 如果您的应用程序代码对其强制执行顺序,则可以控制键的顺序。 - xentek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接