i have trouble aggregation involving objectid. pipelines:
{'$match' : {'likes.id' : objectid('50e99acfb35de75402002023')}} {'$project' : {'likes.id' : 1, '_id' : 0}} {'$unwind' : '$likes'} {'$group' : {'_id' : '$likes.id', 'count' : {'$sum':1}}} {'$sort' : {'_id' : 1}} my attempt write in r using rmongodb is:
pipe_1 <- mongo.bson.from.json('{"$match" : {"likes.id" : { "$oid" : "50e99acfb35de75402002023" }}}') pipe_2 <- mongo.bson.from.json('{"$project" : {"likes.id" : 1, "_id" : 0}}') pipe_3 <- mongo.bson.from.json('{"$unwind" : "$likes"}') pipe_4 <- mongo.bson.from.json('{"$group" : {"_id" : "$likes.id", "count" : {"$sum":1}}}') pipe_5 <- mongo.bson.from.json('{"$sort" : {"count" : 1}}') pipes <- list(pipe_1,pipe_2,pipe_3,pipe_4,pipe_5) result <- mongo.aggregation(mongo, ns = "analytics.analytics_profiles", pipeline =pipes) which returns
mongodb error: 10 that corresponds bson invalid error code.
i think problem match objectid: first pipeline alone gives same error.
how can fix this?
extra: how can done using mongolite instead?
you should not "dot notation" "array" key in aggregation pipeline, doing still valid. can reduce array elements "id" values $project though:
also looks might need contruct bson matching objectid seperately:
oid <- mongo.oid.from.string("50e99acfb35de75402002023") pipe_1 <- mongo.bson.from.list(list('$match' = list('likes.id' = oid))) pipe_2 <- mongo.bson.from.json('{"$project" : {"likes" : "$likes.id", "_id" : 0}}') pipe_3 <- mongo.bson.from.json('{"$unwind" : "$likes"}') pipe_4 <- mongo.bson.from.list(list('$match' = list('likes' = oid))) pipe_5 <- mongo.bson.from.json('{"$group" : {"_id" : "$likes", "count" : {"$sum":1}}}') pipe_6 <- mongo.bson.from.json('{"$sort" : {"count" : 1}}') that makes "likes" array of values , not "key/value" pair. don't need "$likes.id" in later stages. reference "$likes".
--
for record, went through sample document collection seem have defined:
{ "_id" : objectid("50e99acfb35de75402002023"), "likes" : [ { "id" : objectid("50e99acfb35de75402002023") }, { "id" : objectid("50e99acfb35de75402002023") }, { "id" : objectid("50e99acfb35de75402002023") }, { "id" : objectid("50e99acfb35de75402002023") } ] } then defined pipeline in r using bson.from.list` contructors so:
pipeline <- list( mongo.bson.from.list(list( '$match' = list( 'likes.id' = mongo.oid.from.string("50e99acfb35de75402002023") ) )), mongo.bson.from.list(list( '$project' = list( '_id' = 0, 'likes' = '$likes.id' ) )), mongo.bson.from.list(list( '$unwind' = '$likes' )), mongo.bson.from.list(list( '$match' = list( 'likes' = mongo.oid.from.string("50e99acfb35de75402002023") ) )), mongo.bson.from.list(list( '$group' = list( '_id' = '$likes', 'count' = list( '$sum' = 1 ) ) )), mongo.bson.from.list(list( '$sort' = list( 'count' = 1 ) )) ) mongo.aggregation(mongo, "test.posts", pipeline) and me correctly adds matching entries within array.
also "note" additional match stage here after $unwind. first $match in aggregation matches "document", nothing "filter" array content, items in array still contain things not match "id" value asked for.
so after processing $unwind need "filter" $match again once array has been denormalized. there more efficient ways of doing , documented on site even: retrieve queried element in object array in mongodb collection
but should using bson.from.list , general list() contructors structure rather converting json.
Comments
Post a Comment