【发布时间】:2018-11-05 09:20:56
【问题描述】:
假设我有一组如下所示的文档:
{
"_id" : ObjectId("5afa6df3a24cdb1652632ef5"),
"createdBy" : {
"_id" : "59232a1a41aa651ddff0939f"
},
"owner" : {
"_id" : "5abc4dc0f47f732c96d84aac"
},
"acl" : [
{
"profile" : {
"_id" : "59232a1a41aa651ddff0939f"
}
},
{
"profile" : {
"_id" : "5abc4dc0f47f732c96d84aac"
}
}
]
}
我想查找createdBy._id != owner._id 和createdBy._id 出现在acl 数组中的一个条目中的所有文档。最终,我将要更新所有此类文档以将owner._id 字段设置为等于createdBy._id 字段。现在,我只是想弄清楚如何查询我想要更新的文档子集。
到目前为止,我想出了这个:
db.boards.find({
$where: "this.createdBy._id != this.owner._id",
$where: function() {
return this.acl.some(
function(e) => {
e.profile._id === this.createdBy._id
}, this);
}
)
(我使用了 ES5 语法,以防 ES6 不行)
但是当我运行这个查询时,我得到了以下错误:
错误: 错误: { "ok" : 0, "errmsg" : "TypeError: e.profile is 未定义:\n_funcs2/
如何执行此查询/这里发生了什么?根据我读过的docs,我本来希望我的查询能够工作。上面,e 应该是acl 数组的一个元素,所以我希望它有一个字段profile,但似乎并非如此。
注意,我使用的是 Mongo 3.2,所以我不能使用 $expr,我已经看到一些资源表明这是可能的。
分辨率
事实证明,我对这个集合的架构做出了错误的假设。我遇到上述错误的原因是因为某些文档有一个 acl 数组,其中一个元素没有 profile 字段。下面的查询检查这种情况。它也有一个$where,因为我最初编写它的方式(有两个)似乎最终给了我条件的 OR 而不是 AND。
db.boards.find({
$where: function() {
return this.acl.some(
function(e) => {
e.profile !== undefined && e.profile._id === this.createdBy._id && this.createdBy._id != this.owner._id
}, this);
}
)
【问题讨论】:
-
您认为提供的答案中是否有某些内容无法解决您的问题?如果是这样,那么请对答案发表评论,以澄清究竟需要解决哪些尚未解决的问题。如果它确实回答了您提出的问题,请注意Accept your Answers您提出的问题
标签: javascript mongodb mongodb-query aggregation-framework