如何在Mongoose/MongoDB中查询子对象含指定值的Trial授权文档
问题描述
需要查找同时满足以下两个条件的文档:
licenseType等于"Trial"machineId对象中至少有一个值匹配"ABC"
文档结构示例:
{ "licenseType": "Trial", "machineId": { "0": null, "1": "ABC", "2": "null", ... } }
当前使用的Mongoose查询无法正常工作:
const licenses = await License.exists({ machineId: { $in: ["ABC"] }, licenseType: "Trial", })
需求:实现查询machineId任意值等于"ABC"的文档,同时需要JavaScript(Mongoose)和MongoDB命令行的实现方法,方便在代码外复现查询。
解决方案
Mongoose/JavaScript 实现
MongoDB提供$where操作符,可以直接执行类似JavaScript的逻辑判断,用来检查machineId对象的所有值里是否包含"ABC"。注意:$where会遍历集合内的文档,数据量较大时可能影响性能,如果这个查询是高频操作,建议后续调整数据结构(比如把machineId改成数组)。
使用exists()方法
const exists = await License.exists({ licenseType: "Trial", $where: function() { return Object.values(this.machineId).includes("ABC"); } });
使用findOne()方法
如果需要拿到具体文档而非仅判断存在性,可以用findOne():
const license = await License.findOne({ licenseType: "Trial", $where: function() { return Object.values(this.machineId).includes("ABC"); } }); const exists = !!license; // 转换为布尔值判断是否存在
MongoDB命令行实现
在MongoDB shell里,同样用$where实现相同逻辑:
检查文档是否存在
db.licenses.exists({ licenseType: "Trial", $where: function() { return Object.values(this.machineId).includes("ABC"); } })
查询具体文档
db.licenses.findOne({ licenseType: "Trial", $where: function() { return Object.values(this.machineId).includes("ABC"); } })
性能优化方案
如果这个查询是高频操作,建议把machineId从对象改成数组结构,示例如下:
{ "licenseType": "Trial", "machineIds": [null, "ABC", "null", ...] }
改成数组后,就可以直接用$in查询,性能更优:
// Mongoose代码 const exists = await License.exists({ licenseType: "Trial", machineIds: { $in: ["ABC"] } }); // MongoDB shell命令 db.licenses.exists({ licenseType: "Trial", machineIds: { $in: ["ABC"] } })
内容的提问来源于stack exchange,提问作者Thano
相关产品推荐
相关产品推荐

