概要
Mongoシェルの**db.collection.find()**でprojection
はフィールドの出力可否しかできない。Aggregationの$project
ようにもっといろいろなことが出来たら良いと思います。そこで、**db.collection.aggregate()**を使って新しいdb.collection.agfind(query, projection, others)
を作ってみます。
コマンドの追加の詳細は「mongoシェルのdb,collectionにコマンドの追加」を参照してください。
実装例
DBCollection.prototype.agfind = function(query, proj, others) {
let pipeline = []
if (query!= undefined && Object.keys(query).length > 0) {
pipeline.push({$match: query})
}
if (proj != undefined && Object.keys(proj).length > 0) {
pipeline.push({$project: proj})
}
if (others != undefined && Object.keys(others).length > 0) {
Object.keys(others).forEach(key => {
let doc={}
doc["$"+key] = others[key]
pipeline.push(doc)
})
}
return this.aggregate(pipeline)
}
Object.keys(match).length > 0
は空ドキュメントのときはPipelineに入れないため。
others
は追加のPipeline Stageを配列でなくドキュメントで記述し、Stage名の$
は付けない。例として次のように記述します。
[{$sort:{field1:1}}, {$limit:1}]
は
{sort:{field1:1}, limit:1}
とする。
実行例
データの作成
db.col.insert([
{a:1, b:11, c:"abc"},
{a:2, b:22, c:"opqr"},
{a:3, b:33, c:"xyz"}
])
まずは通常のfind
と同じ使い方
> db.col.agfind()
{ "_id" : ObjectId("5d8035a3047fb359c5337c0a"), "a" : 1, "b" : 11, "c" : "abc" }
{ "_id" : ObjectId("5d8035a3047fb359c5337c0b"), "a" : 2, "b" : 22, "c" : "opqr" }
{ "_id" : ObjectId("5d8035a3047fb359c5337c0c"), "a" : 3, "b" : 33, "c" : "xyz" }
> db.col.agfind({a:{$gt:1}},{_id:0,a:1,b:1})
{ "a" : 2, "b" : 22 }
{ "a" : 3, "b" : 33 }
a,b,c
を別名で出力します。
> db.col.agfind({},{_id:0,数量:"$a", 金額:"$b", メモ:"$c"})
{ "数量" : 1, "金額" : 11, "メモ" : "abc" }
{ "数量" : 2, "金額" : 22, "メモ" : "opqr" }
{ "数量" : 3, "金額" : 33, "メモ" : "xyz" }
a+b
をtotal
として出力します。
> db.col.agfind({},{_id:0, total:{$add:["$a","$b"]}})
{ "total" : 12 }
{ "total" : 24 }
{ "total" : 36 }
others
を使ってみます。
> db.col.agfind({},{_id:0, total:{$add:["$a","$b"]}, c:1}, {sort:{total:-1}, limit:2})
{ "c" : "xyz", "total" : 36 }
{ "c" : "opqr", "total" : 24 }