猫鼬:如何使用聚合并一起找到

时间:2017-02-22 14:55:09

标签: node.js mongodb mongoose mongodb-query aggregation-framework

如何在Mongoose中一起使用aggregatefind? 即我有以下架构:

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)

如何仅使用namefollowers_count字段查询用户 followers_countfollowers的长度。

在那里,我知道我们可以使用select来仅获取字段name 我们怎样才能获得followers的数量?

2 个答案:

答案 0 :(得分:20)

对于MongoDB 3.6及更高版本,请使用 $expr 运算符,该运算符允许在查询语言中使用聚合表达式:

var followers_count = 30;
db.locations.find({
   "$expr": { 
       "$and": [
           { "$eq": ["$name", "development"] },
           { "$gte": [{ "$size": "$followers" }, followers_count ]}
       ]
    }
});

对于不兼容的版本,您可以同时使用 $match $redact 管道来查询您的收藏集。例如,如果您要查询locations集合,其名称为' 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);
})

或在单个管道中

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);
})

以上内容将返回仅包含用户_id引用的位置。返回用户文档作为"填充"在关注者数组中,您可以添加 $lookup 管道。

如果底层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);
})

否则在应用 $unwind 之前,您需要 $lookup 关注数组,然后重新组合 $group < / strong>管道之后:

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);
})

答案 1 :(得分:6)

您可以使用以下内容:

db.locations.aggregate([
  {$match:{"your find query"}},
  {$project:{"your desired fields"}}
])

在比赛中,您可以执行以下操作:

{{$match:{name:"whatever"}}

在项目中,您可以使用数字0或1选择所需的字段,如:

{$project:{_id:1,created:0,name:1}}

其中0表示不放1表示放置。