在MongoDB中查询内部数组大小
考虑users
集合中的MongoDB文档:
{ username : 'Alex', tags: ['C#', 'Java', 'C++'] }
有什么办法,从服务器端获取tags
数组的长度(不通过标签到客户端)?
谢谢!
现在,MongoDB(2.6版本) 支持聚合中的$size
操作。
从文档:
{ <field>: { $size: <array> } }
你可以用下面的方法完成你想要的任务:
db.users.aggregate( [ { $group: { _id: "$username", tags_count: {$first: {$size: "$tags" }} } } ] )
要么
db.users.aggregate( [ { $project: { tags_count: {$size: "$tags"} } } ] )
如果用户名Alex是唯一的,你可以使用下面的代码:
db.test.insert({username:"Alex", tags: ['C#', 'Java', 'C++'] }); db.test.aggregate( {$match: {username : "Alex"}}, {$unwind: "$tags"}, {$project: {count:{$add:1}}}, {$group: {_id: null, number: {$sum: "$count" }}} ); { "result" : [ { "_id" : null, "number" : 3 } ], "ok" : 1 }
我认为使用$ inc或者通过计划中的工作来计算每次保存(作为单独字段)的标签数量可能更有效。
你也可以用map / reduce( 规范的例子 )做到这一点,但这似乎不是你想要的。
我不确定是否有可能完全按照你所要求的方式,但是你可以用$ size来查询所有与特定大小相匹配的文档。
> db.collection.find({ tags : { $size: 3 }});
那会给你带有3个标签的所有文件
xmm.dev的答案可以简化:不用interm字段“count”,你可以直接在$ group中求和:
db.test.aggregate( {$match: {username : "Alex"}}, {$unwind: "$tags"}, {$group: {_id: null, number: {$sum: 1 }}} )
目前,唯一的办法似乎是使用db.eval
,但是这会locking其他操作的数据库 。
最快速的方法是增加一个额外的字段来存储数组的长度,并通过$ inc和$ push操作维护它。
我做了一个小的工作,因为我需要查询数组的大小,并返回,如果它大于0,但可能是从1-3的任何东西。
这是我的解决scheme:
db.test.find($or : [{$field : { $exists : true, $size : 1}}, {$field : { $exists : true, $size : 2}}, {$field : { $exists : true, $size : 3}}, ])
当属性存在且大小为1,2或3时,基本上会返回文档。如果用户正在查找特定大小或范围内,则可以添加更多的语句并递增。 我知道它不完美,但它确实有效,而且速度相对较快。 我的属性只有1-3大小,所以这个解决scheme工作。