在 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 12:09:59  来源:igfitidea点击:

Querying internal array size in MongoDB

mongodbmongodb-querynosql

提问by Zaur Nasibov

Consider a MongoDB document in userscollection:

考虑users集合中的 MongoDB 文档:

{ username : 'Alex', tags: ['C#', 'Java', 'C++'] }

Is there any way, to get the length of the tagsarray from the server side (without passing the tags to the client) ?

有什么办法可以tags从服务器端获取数组的长度(不将标签传递给客户端)?

Thank you!

谢谢!

采纳答案by anvarik

Now MongoDB (2.6 release) supports$sizeoperation 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.

最高效的方法是添加一个额外的字段来存储数组的长度并通过$inc$push操作维护它。

回答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 个尺寸,因此此解决方案有效。