javascript – 查找字段与数组中的另一个字段比较的文档
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了javascript – 查找字段与数组中的另一个字段比较的文档,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3149字,纯文字阅读大概需要5分钟。
内容图文
![javascript – 查找字段与数组中的另一个字段比较的文档](/upload/InfoBanner/zyjiaocheng/789/d389c107e29242b0b53e7c4df01ec610.jpg)
假设我有一组看起来像这样的文档:
{
"_id" : ObjectId("5afa6df3a24cdb1652632ef5"),
"createdBy" : {
"_id" : "59232a1a41aa651ddff0939f"
},
"owner" : {
"_id" : "5abc4dc0f47f732c96d84aac"
},
"acl" : [
{
"profile" : {
"_id" : "59232a1a41aa651ddff0939f"
}
},
{
"profile" : {
"_id" : "5abc4dc0f47f732c96d84aac"
}
}
]
}
我想找到createdBy._id!= owner._id,AND的所有文件,其中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不行)
但是当我运行此查询时,我收到以下错误:
Error: error: { “ok” : 0, “errmsg” : “TypeError: e.profile is
undefined :\n_funcs2/<@:2:36\n_funcs2@:2:12\n”, “code” : 139 }
我如何执行此查询/此处发生了什么?根据我读过的docs,我本来期望我的查询能够正常工作.上面,e应该是acl数组的一个元素,所以我希望它有一个字段配置文件,但似乎并非如此.
注意,我使用的是Mongo 3.2,所以我不能使用$expr,我已经看到一些资源建议是可能的.
解析度
事实证明,我对这个集合的架构做了一个不正确的假设.我遇到上述错误的原因是因为某些文档有一个acl数组,其元素没有配置文件字段.以下查询检查此案例.它还有一个$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);
}
)
解决方法:
您仍然可以在MongoDB 3.2中使用aggregate(),但只使用$redact:
db.boards.aggregate([
{ "$redact": {
"$cond": {
"if": {
"$and": [
{ "$ne": [ "$createdBy._id", "$owner._id" ] },
{ "$setIsSubset": [["$createdBy._id"], "$acl.profile._id"] }
]
},
"then": "$$KEEP",
"else": "$$PRUNE"
}
}}
])
或者使用$where for MongoDB 3.2 shell,你只需要保留这个的范围副本,你的语法有点偏:
db.boards.find({
"$where": function() {
var self = this;
return (this.createdBy._id != this.owner._id)
&& this.acl.some(function(e) {
return e.profile._id === self.createdBy._id
})
}
})
或者在ES6兼容环境中:
db.boards.find({
"$where": function() {
return (this.createdBy._id != this.owner._id)
&& this.acl.some(e => e.profile._id === this.createdBy._id)
}
})
聚合是两者中性能最高的选项,应始终优于使用JavaScript评估
对于它的价值,$expr的新语法将是:
db.boards.find({
"$expr": {
"$and": [
{ "$ne": [ "$createdBy._id", "$owner._id" ] },
{ "$in": [ "$createdBy._id", "$acl.profile._id"] }
]
}
})
使用$in优先于$setIsSubset,其语法稍短.
NOTE The only reason the JavaScript comparison here works is because you have mistakenly stored
ObjectId
values as “strings” in those fields. Where there is a “real”ObjectId
just like in the_id
field, the comparison needs to take the “string” fromvalueOf()
in order to compare:
return (this.createdBy._id.valueOf() != this.owner._id.valueOf())
&& this.acl.some(e => e.profile._id.valueOf() === this.createdBy._id.valueOf())
Without that it’s actually an “Object Comparison” with JavaScript and
{ a: 1 } === { a: 1 }
is actuallyfalse
. So avoiding that complexity is another reason there are native operators for this instead.
内容总结
以上是互联网集市为您收集整理的javascript – 查找字段与数组中的另一个字段比较的文档全部内容,希望文章能够帮你解决javascript – 查找字段与数组中的另一个字段比较的文档所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。