7

我如何在貓鼬中使用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_count:長度爲followers

在那裏,我知道我們可以使用select得到只有字段name
我們怎樣才能得到followers的計數?

回答

7

MongoDB的3.6和更大,使用$expr運營商允許查詢語言中使用聚合表達式:

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

對於非兼容版本,你可以同時使用$match$redact管道查詢您的收藏。例如,如果你想查詢locations集合,其中名稱是「發展」和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引用的位置。要返回用戶文檔作爲「填充」關注者數組的手段,可以添加流水線。


如果底層蒙戈服務器版本3.4及更高版本,你可以在應用$lookup前的追隨者陣列運行的管道作爲

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,然後重新集結與$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); 
}) 
4

您可以按照下面的使用:

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表示放。