使用 mongoid 通过聚合计算数组大小
Use mongoid to count array size with aggregate
我正在尝试将聚合从 MongoDB shell 转换为使用 Mongoid 作为 ODM 的 ruby 代码。
我有一些这样的文件(非常简单的例子):
{
"name": "Foo",
"tags": ["tag1", "tag2", "tagN"]
},
{
"name": "Bar",
"tags": ["tagA", "tag2"]
},
...
现在我想获取所有带有名称字段的文档以及每个文档的标签总数。
在 MongoDB shell 中,我可以使用这样的聚合框架来实现它:
db.documents.aggregate(
{$project: {name: 1, tags_count: {$size: $tags}}
)
它会 return:
[{"name": "Foo", "tags_count": 3},
{"name": "Bar", "tags_count": 2}]
现在是令人沮丧的部分,我正在尝试使用 Mongoid 作为 ODM 在 rails 应用程序中实现相同的查询。
代码如下(使用 rails 控制台):
Document.collection.aggregate(
[
{'$project': {name: 1, tags_count: {'$size': '$tags'}}}
]
).to_a
它 return 是下一个错误:
Mongo::Error::OperationFailure: The argument to $size must be an Array, but was of type: EOO (17124)
我的问题是:如何让 Mongoid 理解 $tags
引用了正确的字段?或者代码中缺少什么?
谢谢
看起来有些数据字段中的数组并不一致。为此,您可以使用 $ifNull
在找到 none 的位置放置一个空数组,因此 return $size
为 0
:
Document.collection.aggregate(
[
{'$project': {name: 1, tags_count: {'$size': { '$ifNull': [ '$tags', [] ] } } }}
]
).to_a
或者,您可以使用 $exists
:
跳过根本不存在该字段的地方
Document.collection.aggregate(
[
{'$match': { 'tags_count': { '$exists': true } } },
{'$project': {name: 1, tags_count: {'$size': '$tags'}}}
]
).to_a
当然,这会从选择中过滤掉那些文档,这可能是也可能不是预期的效果。
我正在尝试将聚合从 MongoDB shell 转换为使用 Mongoid 作为 ODM 的 ruby 代码。
我有一些这样的文件(非常简单的例子):
{
"name": "Foo",
"tags": ["tag1", "tag2", "tagN"]
},
{
"name": "Bar",
"tags": ["tagA", "tag2"]
},
...
现在我想获取所有带有名称字段的文档以及每个文档的标签总数。
在 MongoDB shell 中,我可以使用这样的聚合框架来实现它:
db.documents.aggregate(
{$project: {name: 1, tags_count: {$size: $tags}}
)
它会 return:
[{"name": "Foo", "tags_count": 3},
{"name": "Bar", "tags_count": 2}]
现在是令人沮丧的部分,我正在尝试使用 Mongoid 作为 ODM 在 rails 应用程序中实现相同的查询。
代码如下(使用 rails 控制台):
Document.collection.aggregate(
[
{'$project': {name: 1, tags_count: {'$size': '$tags'}}}
]
).to_a
它 return 是下一个错误:
Mongo::Error::OperationFailure: The argument to $size must be an Array, but was of type: EOO (17124)
我的问题是:如何让 Mongoid 理解 $tags
引用了正确的字段?或者代码中缺少什么?
谢谢
看起来有些数据字段中的数组并不一致。为此,您可以使用 $ifNull
在找到 none 的位置放置一个空数组,因此 return $size
为 0
:
Document.collection.aggregate(
[
{'$project': {name: 1, tags_count: {'$size': { '$ifNull': [ '$tags', [] ] } } }}
]
).to_a
或者,您可以使用 $exists
:
Document.collection.aggregate(
[
{'$match': { 'tags_count': { '$exists': true } } },
{'$project': {name: 1, tags_count: {'$size': '$tags'}}}
]
).to_a
当然,这会从选择中过滤掉那些文档,这可能是也可能不是预期的效果。