MongoDB Aggregate lookup in Go (mgo.v2) -
i'm trying implement $lookup
functionality in 1 of mongodb queries in go (golang) using mgo package.
below collections:
folders:
"_id" : objectid("22222222222222"), "name" : "media", "level" : 1, "userids": [objectid("4444444444444")]
documents:
"_id" : objectid("11111111111111"), "title" : "media management", "body" : bindata(0,"pvq6z2nbm4265duo/e2xsyxa5bxko="), "level" : 1, "folderid" : objectid("22222222222222"), // foreign key/field "userids" : [objectid("44444444444444")]
below query i've written runs on shell:
var query = [ { "$lookup": { "from": "documents", "localfield": "_id", "foreignfield": "folderid", "as": "documents", } } ,{ "$match": { "userids": objectid("useridhere"), // filder userid "level": {$gte: 0}, // filter folder level }, } ]; db.folders.aggregate(query).pretty().shellprint();
if run script on shell, desired result. basically, folder
collection returned me containing full relevant documents
linked through $lookup
. i'm not including here because question seems long.
i've tried translate query mgo able parse , execute. here below in go code:
query := bson.m{ "$lookup": bson.m{ // lookup documents table here "from": "documents", "localfield": "_id", "foreignfield": "folderid", "as": "documents", }, "$match": bson.m{ "level": bson.m{"$gte": user.level}, // filter level "userids": user.id, // filter user }, } pipe := collection.pipe(query) // querying "folders" collection err := pipe.all(&result)
i same error: wrong type field (pipeline) 3 != 4
if understand correctly, it's because can't parse result $result object. i've done can ensure struct has exact structure required. i've tried pass in genereric []interface{}
, empty bson.m{}
objects. still receive same error.
below folders struct:
type folder struct { id bson.objectid `json:"id" bson:"_id"` name string `json:"name"` level int `json:"level"` userids []bson.objectid `json:"userids" bson:"userids"` users []user `json:"-" bson:"-"` // doesn't stored in database documents []document `json:"-" bson:"-"` // doesn't stored in database }
i've removed $match
clause see if @ $lookup
query. still same error.
perhaps mgo package doesn't support $lookup
? if so, there way? perhaps send raw query text mongo , receive raw response , parse myself?
found solution!
the trick create query in slice ([]bson.m
) , change structure of query bit:
query := []bson.m{{ "$lookup": bson.m{ // lookup documents table here "from": "documents", "localfield": "_id", "foreignfield": "folderid", "as": "documents", }}, {"$match": bson.m{ "level": bson.m{"$lte": user.level}, "userids": user.id, }}} pipe := collection.pipe(query) err := pipe.all(&folders)
i found clue in mgo's pipe function docs. also, had change tags documents
field in folders
struct mgo pupolate field:
type folder struct { id bson.objectid `json:"id" bson:"_id"` name string `json:"name"` level int `json:"level"` userids []bson.objectid `json:"userids" bson:"userids"` users []user `json:"-" bson:"-"` // doesn't stored in database documents []document // `json:"-" bson:"-" removed mgo can unmarshal // documents correctly }
now have figure out way not store documents
field in database when save folder
.
Comments
Post a Comment