How can I use aggregate and find
together in Mongoose?
i.e I have the following schema:
如何在Mongoose中使用聚合并一起查找?即我有以下架构:
const schema = new Mongoose.Schema({
created: { type: Date, default: Date.now() },
name: { type: String, default: 'development' }
followers: [{ type: Mongoose.Schema.ObjectId, ref: 'Users'}]
...
})
export default Mongoose.model('Locations', schema)
How can I query the users with only the fields name
and followers_count
.followers_count
: the length of followers
.
如何仅使用字段名称和followers_count查询用户。 followers_count:粉丝的长度。
There, I know we can use select to get only the field name
.
How can we get the count of followers
?
在那里,我知道我们可以使用select来获取字段名称。我们怎样才能得到粉丝的数量?
2 个解决方案
#1
12
For MongoDB 3.6 and greater, use the $expr
operator which allows the use of aggregation expressions within the query language:
对于MongoDB 3.6及更高版本,请使用$ expr运算符,该运算符允许在查询语言中使用聚合表达式:
var followers_count = 30;
db.locations.find({
"$expr": {
"$and": [
{ "$eq": ["$name", "development"] },
{ "$gte": [{ "$size": "$followers" }, followers_count ]}
]
}
});
For non-compatible versions, you can use both the $match
and $redact
pipelines to query your collection. For example, if you want to query the locations
collection where the name is 'development' and followers_count
is greater than 30, run the following aggregate operation:
对于不兼容的版本,您可以使用$ match和$ redact管道来查询您的集合。例如,如果要查询名称为“development”且followers_count大于30的位置集合,请运行以下聚合操作:
const followers_count = 30;
Locations.aggregate([
{ "$match": { "name": "development" } },
{
"$redact": {
"$cond": [
{ "$gte": [ { "$size": "$followers" }, followers_count ] },
"$$KEEP",
"$$PRUNE"
]
}
}
]).exec((err, locations) => {
if (err) throw err;
console.log(locations);
})
or within a single pipeline as
或者在一个管道内
Locations.aggregate([
{
"$redact": {
"$cond": [
{
"$and": [
{ "$eq": ["$name", "development"] },
{ "$gte": [ { "$size": "$followers" }, followers_count ] }
]
},
"$$KEEP",
"$$PRUNE"
]
}
}
]).exec((err, locations) => {
if (err) throw err;
console.log(locations);
})
The above will return the locations with just the _id
references from the users. To return the users documents as means to "populate" the followers array, you can then append the $lookup
pipeline.
以上将返回仅包含用户的_id引用的位置。要返回用户文档作为“填充”关注者数组的方法,您可以附加$ lookup管道。
If the underlying Mongo server version is 3.4 and newer, you can run the pipeline as
如果底层Mongo服务器版本为3.4及更高版本,则可以将管道作为
let followers_count = 30;
Locations.aggregate([
{ "$match": { "name": "development" } },
{
"$redact": {
"$cond": [
{ "$gte": [ { "$size": "$followers" }, followers_count ] },
"$$KEEP",
"$$PRUNE"
]
}
},
{
"$lookup": {
"from": "users",
"localField": "followers",
"foreignField": "_id",
"as": "followers"
}
}
]).exec((err, locations) => {
if (err) throw err;
console.log(locations);
})
else you would need to $unwind
the followers array before applying $lookup
and then regroup with $group
pipeline after that:
否则你需要在应用$ lookup之前展开追随者数组,然后重新组合$ group管道:
let followers_count = 30;
Locations.aggregate([
{ "$match": { "name": "development" } },
{
"$redact": {
"$cond": [
{ "$gte": [ { "$size": "$followers" }, followers_count ] },
"$$KEEP",
"$$PRUNE"
]
}
},
{ "$unwind": "$followers" },
{
"$lookup": {
"from": "users",
"localField": "followers",
"foreignField": "_id",
"as": "follower"
}
},
{ "$unwind": "$follower" },
{
"$group": {
"_id": "$_id",
"created": { "$first": "$created" },
"name": { "$first": "$name" },
"followers": { "$push": "$follower" }
}
}
]).exec((err, locations) => {
if (err) throw err;
console.log(locations);
})
#2
5
You can use as the following:
您可以使用如下:
db.locations.aggregate([
{$match:{"your find query"}},
{$project:{"your desired fields"}}
])
In the match you can do stuff like:
在比赛中你可以做的事情:
{{$match:{name:"whatever"}}
In the project, you can select the fields you want using numbers 0 or 1 like:
在项目中,您可以使用数字0或1选择所需的字段,如:
{$project:{_id:1,created:0,name:1}}
Which 0 means, do not put and 1 means put.
其中0表示不放1表示放置。
#1
12
For MongoDB 3.6 and greater, use the $expr
operator which allows the use of aggregation expressions within the query language:
对于MongoDB 3.6及更高版本,请使用$ expr运算符,该运算符允许在查询语言中使用聚合表达式:
var followers_count = 30;
db.locations.find({
"$expr": {
"$and": [
{ "$eq": ["$name", "development"] },
{ "$gte": [{ "$size": "$followers" }, followers_count ]}
]
}
});
For non-compatible versions, you can use both the $match
and $redact
pipelines to query your collection. For example, if you want to query the locations
collection where the name is 'development' and followers_count
is greater than 30, run the following aggregate operation:
对于不兼容的版本,您可以使用$ match和$ redact管道来查询您的集合。例如,如果要查询名称为“development”且followers_count大于30的位置集合,请运行以下聚合操作:
const followers_count = 30;
Locations.aggregate([
{ "$match": { "name": "development" } },
{
"$redact": {
"$cond": [
{ "$gte": [ { "$size": "$followers" }, followers_count ] },
"$$KEEP",
"$$PRUNE"
]
}
}
]).exec((err, locations) => {
if (err) throw err;
console.log(locations);
})
or within a single pipeline as
或者在一个管道内
Locations.aggregate([
{
"$redact": {
"$cond": [
{
"$and": [
{ "$eq": ["$name", "development"] },
{ "$gte": [ { "$size": "$followers" }, followers_count ] }
]
},
"$$KEEP",
"$$PRUNE"
]
}
}
]).exec((err, locations) => {
if (err) throw err;
console.log(locations);
})
The above will return the locations with just the _id
references from the users. To return the users documents as means to "populate" the followers array, you can then append the $lookup
pipeline.
以上将返回仅包含用户的_id引用的位置。要返回用户文档作为“填充”关注者数组的方法,您可以附加$ lookup管道。
If the underlying Mongo server version is 3.4 and newer, you can run the pipeline as
如果底层Mongo服务器版本为3.4及更高版本,则可以将管道作为
let followers_count = 30;
Locations.aggregate([
{ "$match": { "name": "development" } },
{
"$redact": {
"$cond": [
{ "$gte": [ { "$size": "$followers" }, followers_count ] },
"$$KEEP",
"$$PRUNE"
]
}
},
{
"$lookup": {
"from": "users",
"localField": "followers",
"foreignField": "_id",
"as": "followers"
}
}
]).exec((err, locations) => {
if (err) throw err;
console.log(locations);
})
else you would need to $unwind
the followers array before applying $lookup
and then regroup with $group
pipeline after that:
否则你需要在应用$ lookup之前展开追随者数组,然后重新组合$ group管道:
let followers_count = 30;
Locations.aggregate([
{ "$match": { "name": "development" } },
{
"$redact": {
"$cond": [
{ "$gte": [ { "$size": "$followers" }, followers_count ] },
"$$KEEP",
"$$PRUNE"
]
}
},
{ "$unwind": "$followers" },
{
"$lookup": {
"from": "users",
"localField": "followers",
"foreignField": "_id",
"as": "follower"
}
},
{ "$unwind": "$follower" },
{
"$group": {
"_id": "$_id",
"created": { "$first": "$created" },
"name": { "$first": "$name" },
"followers": { "$push": "$follower" }
}
}
]).exec((err, locations) => {
if (err) throw err;
console.log(locations);
})
#2
5
You can use as the following:
您可以使用如下:
db.locations.aggregate([
{$match:{"your find query"}},
{$project:{"your desired fields"}}
])
In the match you can do stuff like:
在比赛中你可以做的事情:
{{$match:{name:"whatever"}}
In the project, you can select the fields you want using numbers 0 or 1 like:
在项目中,您可以使用数字0或1选择所需的字段,如:
{$project:{_id:1,created:0,name:1}}
Which 0 means, do not put and 1 means put.
其中0表示不放1表示放置。