对填充字段的 MongoDB 查询
MongoDB query on populated fields
我有一个名为"活动"的模型,我正在查询(使用猫鼬)。它们的架构如下所示:
var activitySchema = new mongoose.Schema({
actor: {
type: mongoose.Schema.ObjectId,
ref: 'User',
required: true
},
recipient: {
type: mongoose.Schema.ObjectId,
ref: 'User'
},
timestamp: {
type: Date,
default: Date.now
},
activity: {
type: String,
required: true
},
event: {
type: mongoose.Schema.ObjectId,
ref: 'Event'
},
comment: {
type: mongoose.Schema.ObjectId,
ref: 'Comment'
}
});
当我查询它们时,我正在填充actor
、recipient
、event
和comment
字段(所有引用)。之后,我还深入填充了event
字段以获得event.creator
。这是我的查询代码:
var activityPopulateObj = [
{ path: 'event' },
{ path: 'event.creator' },
{ path: 'comment' },
{ path: 'actor' },
{ path: 'recipient' },
{ path: 'event.creator' }
],
eventPopulateObj = {
path: 'event.creator',
model: User
};
Activity.find({ $or: [{recipient: user._id}, {actor: {$in: user.subscriptions}}, {event: {$in: user.attending}}], actor: { $ne: user._id} })
.sort({ _id: -1 })
.populate(activityPopulateObj)
.exec(function(err, retrievedActivities) {
if(err || !retrievedActivities) {
deferred.reject(new Error("No events found."));
}
else {
User.populate(retrievedActivities, eventPopulateObj, function(err, data){
if(err) {
deferred.reject(err.message);
}
else {
deferred.resolve(retrievedActivities);
}
});
}
});
这已经是一个相对复杂的查询,但我需要做更多的事情。如果它命中$or
语句中说{actor: {$in: user.subscriptions}}
的部分,我还需要确保event
的privacy
字段等于字符串public
。我尝试使用 $elemMatch
,但由于必须先填充事件,因此我无法查询其任何字段。我还需要在多个其他查询中实现相同的目标。
有什么方法可以像我描述的那样实现这种进一步的过滤吗?
答案是更改架构。
您已经陷入了许多开发人员在使用关系数据库的历史进入文档数据库开发时遇到的陷阱:MongoDB不是关系数据库,不应被视为关系数据库。
您需要停止考虑外键和完全规范化的数据,而是尽可能保持每个文档的独立性,考虑如何在文档中最好地嵌入相关关联数据。
这并不意味着您也不能保持关联。 这可能意味着这样的结构,您只嵌入必要的详细信息,并在需要时查询完整记录:
var activitySchema = new mongoose.Schema({
event: {
_id: { type: ObjectId, ref: "Event" },
name: String,
private: String
},
// ... other fields
});
重新考虑嵌入策略将大大简化查询,并将查询计数保持在最低限度。 populate
会迅速增加您的计数,随着数据集的增长,这很可能会成为一个问题。
你可以试试下面的聚合。看看这个答案:https://stackoverflow.com/a/49329687/12729769
然后,您可以在查询中使用$addFields中的字段。喜欢
{score: {$gte: 5}}
但由于必须首先填充事件,因此我无法查询其任何字段。
没有做的事。Mongodb不能做连接。进行查询时,一次只能使用一个集合。仅供参考,所有这些猫鼬填充都是额外的、不同的数据库查询来加载这些记录。
我没有时间深入研究架构和应用程序的详细信息,但很可能您需要对数据进行非规范化,并存储需要在主集合中加入的任何事件字段的副本。
- 需要呈现MongoDB查询返回结果的特定索引/位置
- 将一个小型javascript表达式转换为mongodb查询
- MEAN.js MongoDB查询中用户特定计算的属性
- 如何通过node.js嵌套mongodb查询
- Meteor - 将 mongodb 查询分配给变量并将其插入到另一个集合
- MongoDB查询结果作为循环控制器
- MongoDB 查询的可选参数
- 为什么$elemMatch MongoDB查询在具有扩展RexExp EJSON类型的客户端和服务器上的行为不同
- 对填充字段的 MongoDB 查询
- MongoDB查询优化
- 在 mongodb 查询中操作列表
- 使用 Node.js 驱动程序生成动态 mongodb 查询
- MongoDB:查询数组上的浮点数范围
- MongoDB查询字符串与来自角度前端的ISODate
- node.js 和 express :顺序执行流一个接一个的 mongodb 查询请求
- 仅返回MongoDB查询中一个字段的不同值
- 关于mongodb查询
- 使用Express和Mongodb查询API和数据库
- 在Meteor中呈现来自复杂MongoDB查询的模板
- mongodb查询子数组