Мангуст: как использовать aggregate и найти вместе

как я могу использовать совокупность и find вместе в Мангуста?
Я. e у меня есть следующая схема:

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)

как я могу запросить пользователей только с полями name и followers_count.
followers_count - длина followers .

Нет, я знаю, что мы можем использовать выберите получить только поле name.
Как мы можем получить счет followers?

2 ответов


для 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 ссылки от пользователей. Чтобы вернуть документы пользователей как средство "заполнения" массива подписчиков, вы можете добавить $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 трубопровод после этого:

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

вы можете использовать следующим образом:

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 означает поставить.