通过 rmongodb 中的匹配 ObjectId 进行聚合
Aggregate by match ObjectId in rmongodb
我在处理涉及 ObjectId 的聚合时遇到了问题。这是管道:
{'$match' : {'likes.id' : ObjectId('50e99acfb35de75402002023')}}
{'$project' : {'likes.id' : 1, '_id' : 0}}
{'$unwind' : '$likes'}
{'$group' : {'_id' : '$likes.id', 'count' : {'$sum':1}}}
{'$sort' : {'_id' : 1}}
我尝试使用 rmongodb 在 R 中编写它是:
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)
哪个returns
mongoDB error: 10
与 BSON 无效错误代码相对应。
我认为问题出在 ObjectId 的匹配上:单独的第一个管道给出了同样的错误。
我该如何解决这个问题?
额外:如何使用 mongolite 代替?
对于聚合管道中的 "array" 键,您确实不应该 "dot notation",但您所做的仍然完全有效。但是,您可以使用 $project
将数组元素减少到仅 "id" 值:
另外看起来您可能需要构建 BSON 以单独匹配 ObjectId:
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}}')
这使得 "likes" 成为一个仅包含值的数组,而不是 "key/value" 对。所以你在后面的阶段不需要“$likes.id”。仅通过“$likes”引用。
--
郑重声明,我通过一个示例文档来了解这个是一个类似于您定义的集合:
{
"_id" : ObjectId("50e99acfb35de75402002023"),
"likes" : [
{
"id" : ObjectId("50e99acfb35de75402002023")
},
{
"id" : ObjectId("50e99acfb35de75402002023")
},
{
"id" : ObjectId("50e99acfb35de75402002023")
},
{
"id" : ObjectId("50e99acfb35de75402002023")
}
]
}
然后我实际上使用 bson.from.list` 构造函数在 R 中定义了管道,如下所示:
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)
对我来说,正确地添加了数组中的所有匹配条目。
还有 "note" $unwind
之后的附加比赛阶段。聚合中的第一个 $match
匹配 "document",但这对 "filter" 数组内容没有任何作用,因此数组中的项目仍然包含与 "id" 值不匹配的内容你要的。
因此在处理完 $unwind
之后,一旦数组被非规范化,您需要再次 "filter" 和 $match
。实际上有更有效的方法可以做到这一点,并且在这个网站上有很好的记录:Retrieve only the queried element in an object array in MongoDB collection
但是您还应该真正使用 bson.from.list
和通用 list()
结构构造函数,而不是从 JSON.
转换而来
我在处理涉及 ObjectId 的聚合时遇到了问题。这是管道:
{'$match' : {'likes.id' : ObjectId('50e99acfb35de75402002023')}}
{'$project' : {'likes.id' : 1, '_id' : 0}}
{'$unwind' : '$likes'}
{'$group' : {'_id' : '$likes.id', 'count' : {'$sum':1}}}
{'$sort' : {'_id' : 1}}
我尝试使用 rmongodb 在 R 中编写它是:
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)
哪个returns
mongoDB error: 10
与 BSON 无效错误代码相对应。
我认为问题出在 ObjectId 的匹配上:单独的第一个管道给出了同样的错误。
我该如何解决这个问题?
额外:如何使用 mongolite 代替?
对于聚合管道中的 "array" 键,您确实不应该 "dot notation",但您所做的仍然完全有效。但是,您可以使用 $project
将数组元素减少到仅 "id" 值:
另外看起来您可能需要构建 BSON 以单独匹配 ObjectId:
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}}')
这使得 "likes" 成为一个仅包含值的数组,而不是 "key/value" 对。所以你在后面的阶段不需要“$likes.id”。仅通过“$likes”引用。
--
郑重声明,我通过一个示例文档来了解这个是一个类似于您定义的集合:
{
"_id" : ObjectId("50e99acfb35de75402002023"),
"likes" : [
{
"id" : ObjectId("50e99acfb35de75402002023")
},
{
"id" : ObjectId("50e99acfb35de75402002023")
},
{
"id" : ObjectId("50e99acfb35de75402002023")
},
{
"id" : ObjectId("50e99acfb35de75402002023")
}
]
}
然后我实际上使用 bson.from.list` 构造函数在 R 中定义了管道,如下所示:
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)
对我来说,正确地添加了数组中的所有匹配条目。
还有 "note" $unwind
之后的附加比赛阶段。聚合中的第一个 $match
匹配 "document",但这对 "filter" 数组内容没有任何作用,因此数组中的项目仍然包含与 "id" 值不匹配的内容你要的。
因此在处理完 $unwind
之后,一旦数组被非规范化,您需要再次 "filter" 和 $match
。实际上有更有效的方法可以做到这一点,并且在这个网站上有很好的记录:Retrieve only the queried element in an object array in MongoDB collection
但是您还应该真正使用 bson.from.list
和通用 list()
结构构造函数,而不是从 JSON.