gpt4 book ai didi

arrays - MongoDB:计算文档中数组中存在多少具有给定值的项目?

转载 作者:可可西里 更新时间:2023-11-01 10:23:43 25 4
gpt4 key购买 nike

我有一个看起来像这样的文档

{
name : james,
books : [
{
title: title1,
year: 1990
},
{
title: title2,
year: 1990
},
{
title: title3,
year: 1991
}
]
}

假设我想计算 james 在 1990 年拥有多少本书,我该怎么做?我试过以下。但我意识到它不起作用,因为“书籍”是一个数组。

db.collection(collectionName).find({name:james, books: {year: 1990}}).count(function(book_count){
console.log(book_count);
}

任何指针将不胜感激。谢谢!

编辑:

我确实在另一个答案中看到,您可以使用下面的代码来获取整个数组的大小。但我想知道如何使用特定参数获取数组中的项目数。 IE。而不是查看詹姆斯拥有多少本书。我想知道 james 的书在 1990 年出版了多少本。

db.mycollection.aggregate({$project: { count: { $size:"$foo" }}})

最佳答案

聚合框架非常适合这种情况。考虑运行以下管道以获得所需的结果。

pipeline = [
{
"$match": {
"name": "james",
"books.year": 1990
}
},
{
"$project": {
"numberOfBooks": {
"$size": {
"$filter": {
"input": "$books",
"as": "el",
"cond": { "$eq": [ "$$el.year", 1990 ] }
}
}
}
}
}
];
db.collection.pipeline(pipeline);

上面的管道使用了新的 $filter 运算符可用于 MongoDB 3.2 以生成满足指定条件的数组,即它过滤不满足条件的外部元素。初始 $match pipeline 是过滤掉早期进入聚合管道的文档作为管道优化策略所必需的。

$size 运算符接受单个表达式作为参数,然后为您提供结果数组中元素的数量,因此您可以获得所需的书数。


对于不使用 $filter 的替代解决方案 运算符在早期版本中找不到,考虑以下管道操作:

pipeline = [
{
"$match": {
"name": "james",
"books.year": 1990
}
},
{
"$project": {
"numberOfBooks": {
"$size": {
"$setDifference": [
{
"$map": {
"input": "$books",
"as": "el",
"in": {
"$cond": [
{ "$eq": [ "$$el.year", 1990 ] },
"$$el",
false
]
}
}
},
[false]
]
}
}
}
}
];
db.collection.pipeline(pipeline);

$project 流水线阶段涉及拟合 books 数组,以便您删除不包含 1990 年的文档。这可以通过 $setDifference 实现。 $map 运营商。

$map 运算符实质上创建了一个新的数组字段,该字段保存作为数组每个元素的子表达式中的评估逻辑结果的值。 <强> $setDifference 运算符然后返回一个集合,其中的元素出现在第一个集合中但不在第二个集合中;即相对于第一组执行第二组的相对补充。在这种情况下,它将返回包含 1990 年元素和随后的 $size 元素的最终书籍数组。 计算结果数组中元素的数量,从而为您提供图书数量。


对于使用 $unwind 的解决方案 运营商,请记住(感谢@BlakesSeven 在评论中做出的富有洞察力的回应):

Since there is only a single document returned with nothing but a null key and a count, there is no more chance for this breaking that limit than the previous operation with the same output. It's not that $unwind "breaks the limit", it's that it "produces a copy of each document per array entry", which uses more memory ( possible memory cap on aggregation pipelines of 10% total memory ) and therefore also takes "time" to produce as well as "time" to process.

作为最后的手段,运行以下管道:

pipeline = [
{
"$match": {
"name": "james",
"books.year": 1990
}
},
{ "$unwind": "$books" },
{
"$match": { "books.year": 1990 }
},
{
"$group": {
"_id": null
"count": { "$sum": 1 }
}
}
]
db.collection.pipeline(pipeline)

关于arrays - MongoDB:计算文档中数组中存在多少具有给定值的项目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35876100/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com