Mongooseで aggregate とfind
を一緒に使用するにはどうすればよいですか?
i.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
の長さ。
そこで、 select を使用してフィールドname
のみを取得できることを知っています。followers
のカウントを取得するにはどうすればよいですか?
MongoDB 3.6以降の場合、$expr
演算子を使用して、クエリ言語内で集計式を使用できるようにします。
var followers_count = 30;
db.locations.find({
"$expr": {
"$and": [
{ "$eq": ["$name", "development"] },
{ "$gte": [{ "$size": "$followers" }, followers_count ]}
]
}
});
互換性のないバージョンでは、$match
と$redact
コレクションを照会するパイプライン。たとえば、名前が 'development'でfollowers_count
が30より大きいlocations
コレクションを照会する場合は、次の集約操作を実行します。
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は置くことを意味します。