假设我有一组长这样的文件:
{
"_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语法)
但是当我运行这个查询时,我得到了以下错误:
Error: error: { "ok" : 0, "errmsg" : "TypeError: e.profile is undefined :\n_funcs2/<@:2:36\n_funcs2@:2:12\n", "code" : 139 }
我该如何执行这个查询 / 这里发生了什么?根据我阅读的文档,我本来期望我的查询能够正常工作。在上面的代码中,e
应该是acl
数组的一个元素,因此我希望它有一个profile
字段,但事实并非如此。
请注意,我正在使用Mongo 3.2,因此我不能使用一些资源中建议的$expr。
解决方法
事实证明,我对这个集合的模式做出了错误的假设。我遇到上述错误的原因是因为一些文档具有一个acl
数组,其中一个元素没有profile
字段。下面的查询检查了这种情况。它还有一个单一的$where
,因为我最初编写它的方式(使用两个$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);
}
)