品牌:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var BrandSchema = new mongoose.Schema({
name: { type: String, lowercase: true , unique: true, required: true },
photo: { type: String , trim: true},
email: { type: String , lowercase: true},
year: { type: Number},
timestamp: { type : Date, default: Date.now },
description: { type: String},
location: { },
social: {
website: {type: String},
facebook: {type: String },
twitter: {type: String },
instagram: {type: String }
}
});
风格:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var StyleSchema = new mongoose.Schema({
name: { type: String, lowercase: true , required: true},
});
产品
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ProductSchema = new mongoose.Schema({
name: { type: String, lowercase: true , required: true},
brandId : {type: mongoose.Schema.ObjectId, ref: 'Brand'},
styleId: {type: mongoose.Schema.ObjectId, ref: 'Style'},
year: { type: Number },
avgRating: {type: Number}
});
发表:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var PostSchema = new mongoose.Schema({
rating: { type: Number},
upVote: {type: Number},
brandId : {type: mongoose.Schema.ObjectId, ref: 'Brand'},
comment: {type: String},
productId: {type: mongoose.Schema.ObjectId, ref: 'Style'},
styleId: {type: mongoose.Schema.ObjectId, ref: 'Style'},
photo: {type: String}
});
我目前正在使用mongoose populate功能:
exports.productsByBrand = function(req, res){
Product.find({product: req.params.id}).populate('style').exec(function(err, products){
res.send({products:products});
});
};
然而,这是一个菜鸟 - 我已经开始阅读有关mongoose populate的性能问题,因为它实际上只是添加了一个额外的查询。
对于我的帖子,尤其是,这似乎可能会让人费力。这篇文章的目的是成为一个真实的推特/ Instagram类似的饲料。似乎可能是很多查询,这可能会大大减慢我的应用程序。
另外,我希望能够在某些时候按字段搜索prodcuts / post / brand。
我应该考虑嵌套/嵌入这些数据(嵌套/嵌入品牌的产品)吗?
什么是最有效的架构设计或我的设置是否正常 - 鉴于我已指定我想用它?
用户故事:
会有管理员用户。
管理员可以使用品牌架构中的特定字段添加品牌。
品牌将有关联的产品,每个产品将具有样式 /类别。
搜索:
用户将能够按名称和位置搜索品牌(我正在考虑使用角度过滤/标记进行此操作)。
用户可以按字段(名称,样式等)搜索产品。
用户可以通过品牌 产品和样式搜索发布。
发布:
用户可以发布到 Feed中。在制作发布时,他们会选择品牌和产品将帖子与之关联。 帖子将显示品牌名称,产品名称和样式 - 以及新输入的发布字段(照片,评论和评级)。
其他用户可以点击品牌名称链接到品牌显示页面。他们可以单击产品名称链接到产品显示页面。
产品展示页
将显示上述架构中的产品字段 - 包括 Style 架构中的关联样式名称。它还会显示与特定产品相关的发布。
品牌展示页面:
将只显示品牌字段和相关产品。
我主要担心的是帖子,它必须填充/查询品牌,产品和 Style < / em>在Feed中。
同样,我正在考虑是否应将产品嵌入品牌中 - 然后我能够关联品牌 产品和样式与发布以供日后查询?或者,可能是$ lookup或其他聚合功能。
答案 0 :(得分:6)
Mongodb本身不支持连接。所以,mongoose populate是一种外部参考分辨率的尝试。使用mongodb的是你需要设计你的数据:
考虑所涉及的实体及其关系:
现在关于用例:
参考:如果您按ID查找一个实体,那么获取1-2个相关实体并不是一个很大的开销。
列表:当您必须返回大量对象时,每个对象都需要一个额外的查询来获取关联对象。这是一个性能问题。这通常通过处理&#34;页面来减少。一次结果集,每个请求20个记录。让我们假设您查询了20个产品(使用skip
和limit
)。对于20种产品,您可以提取两个id数组,一个引用的样式,以及其他引用的品牌。您使用$in:[ids]
执行2个其他查询,获取品牌和样式对象并将其置于结果集中。这是每页3个查询。用户可以在向下滚动时请求下一页,依此类推。
搜索:您想要搜索产品,但也想指定品牌名称和样式名称。可悲的是,产品型号只适用于款式和品牌。与品牌和产品一起搜索帖子的问题相同。流行的解决方案是维护一个单独的搜索索引&#34;,这是一种表格,它可以准确地存储数据的搜索方式,并在一个地方包含所有可搜索的字段(如品牌名称,样式名称)。手动维护mongodb中的搜索集合可能会很麻烦。这是ElasticSearch的用武之地。由于您已经在使用猫鼬,因此您只需将mongoosastic添加到模型中即可。 ElasticSearch的搜索功能远远超过数据库存储引擎为您提供的功能。
超速:还有一些加速的空间:缓存。附加mongoose-redis-cache,并在Redis内存中频繁重复查询,减少对mongodb的负担。
Twitter喜欢Feeds:现在,如果所有帖子都是公开的,那么按时间顺序为用户列出它们是一个简单的查询。然而,当你介绍&#34;社交网络&#34;特征。然后你需要列出&#34;活动源&#34;的朋友和追随者。关于社交收件箱和扇出列表in mongodb blog有一些智慧。
故事的道德是,并非所有用例都只有&#34; db schema query&#34;解决方案。可伸缩性就是这种情况之一。这就是为什么存在其他工具的原因。