Мангуст: как использовать 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 означает поставить.