在 MongoDB 中查询内部数组大小
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6722850/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Querying internal array size in MongoDB
提问by Zaur Nasibov
Consider a MongoDB document in users
collection:
考虑users
集合中的 MongoDB 文档:
{ username : 'Alex', tags: ['C#', 'Java', 'C++'] }
Is there any way, to get the length of the tags
array from the server side (without passing the tags to the client) ?
有什么办法可以tags
从服务器端获取数组的长度(不将标签传递给客户端)?
Thank you!
谢谢!
采纳答案by anvarik
Now MongoDB (2.6 release) supports$size
operation in aggregation.
现在 MongoDB(2.6 版本)支持$size
聚合操作。
From the documentation:
从文档:
{ <field>: { $size: <array> } }
What you want can be accomplished as following with either by using this:
您可以使用以下任一方法完成您想要的操作:
db.users.aggregate(
[
{
$group: {
_id: "$username",
tags_count: {$first: {$size: "$tags" }}
}
}
]
)
or
或者
db.users.aggregate(
[
{
$project: {
tags_count: {$size: "$tags"}
}
}
]
)
回答by xmm.dev
if username Alex is unique, you can use next code:
如果用户名 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 }
回答by Justin Jenkins
I think it might be more efficient to calculate the number of tags on each save (as a separate field) using $incperhaps or via a job on a schedule.
我认为使用$inc或按计划通过作业计算每次保存(作为单独的字段)的标签数量可能更有效。
You could also do this with map/reduce (the canonical example) but that doesn't seem to be be what you'd want.
您也可以使用 map/reduce(规范示例)来执行此操作,但这似乎不是您想要的。
I'm not sure it's possible to do exactly what you are asking, but you can query all the documents that match a certain size with $size...
我不确定是否可以完全按照您的要求执行操作,但是您可以使用$size查询与特定大小匹配的所有文档...
> db.collection.find({ tags : { $size: 3 }});
That'd get you all the documents with 3 tags ...
这将为您提供带有 3 个标签的所有文档......
回答by Volodymyr Metlyakov
xmm.dev's answer can be simplified: instead of having interm field 'count', you can sum directly in $group:
xmm.dev 的答案可以简化:您可以直接在 $group 中求和,而不是使用 interterm 字段 'count':
db.test.aggregate(
{$match: {username : "Alex"}},
{$unwind: "$tags"},
{$group: {_id: null, number: {$sum: 1 }}}
)
回答by plaes
Currently, the only way to do it seems to be using db.eval
, but this locks database for other operations.
目前,唯一的方法似乎是使用db.eval
,但这会锁定数据库以进行其他操作。
The most speed-efficient way would be adding an extra field that stores the length of the array and maintaining it by $incand $pushoperations.
回答by kwoodson
I did a small work around as I needed to query the array size and return if it was greater than 0 but could be anything from 1-3.
我做了一个小工作,因为我需要查询数组大小并返回它是否大于 0,但可以是 1-3 之间的任何值。
Here was my solution:
这是我的解决方案:
db.test.find($or : [{$field : { $exists : true, $size : 1}},
{$field : { $exists : true, $size : 2}},
{$field : { $exists : true, $size : 3}}, ])
This basically returns a document when the attribute exists and the size is 1, 2, or 3. The user can add more statements and increment if they are looking for a specific size or within a range. I know its not perfect but it did work and was relatively quick. I only had 1-3 sizes in my attribute so this solution worked.
当属性存在且大小为 1、2 或 3 时,这基本上返回一个文档。如果用户正在寻找特定大小或在一个范围内,他们可以添加更多语句和增量。我知道它并不完美,但它确实有效,而且速度相对较快。我的属性中只有 1-3 个尺寸,因此此解决方案有效。