假设您有一个人员数据库。
[
#1 {qualities: ['brown', 'nice', 'happy' 'cool' 'cheery']}
#2 {qualities: ['blue', 'okay', 'happy' 'decent' 'cheery']}
#3 {qualities: ['green', 'alright', 'happy' 'cool' 'cheery']}
]
这里是人员架构和模型:
var peopleSchema = mongoose.Schema({
qualities: [],
});
var People = mongoose.model('People', peopleSchema);
如果您想根据最大匹配文档获取数据,那么我们使用聚合查询:
People.aggregate([
{$unwind:"$qualities"},
{$match:{'qualities': {$in: ["brown", "happy", "cool"]}}},
{$group:{_id:"$_id",count:{$sum:1}}},
{$sort:{count:-1}}
]).exec(function(err, persons) {
console.log(persons)
});
它将返回 1,3,2 ,因为第一个与 3 相匹配 商品,第三个与 2 商品匹配,第二个商品与 1 商品相匹配。
这个聚合对我的10,000人数据库来说很快 - 事实上,它在273.199ms完成了这个。但是,如何获得1000万条MongoDB的入场券?如果这些速率成比例[100k:2.7s,1m:27s,10m:4m30s],则可能需要4分30秒。也许速度不成比例,我不知道。但是,如果我的时间假设恰好是真的,是否有任何优化或建议来查询如此庞大的数据库?
答案 0 :(得分:1)
好。所以,如果你问过, 我将要求您研究聚合查询的工作原理。
聚合查询基于管道阶段工作:
现在,pipeline stage
是什么: - 从你的例子中
{$unwind:"$qualities"},
{$match:{'qualities': {$in: ["brown", "happy", "cool"]}}},
{$group:{_id:"$_id",count:{$sum:1}}},
{$sort:{count:-1}}
此处,所有展开,匹配,分组和排序都是管道阶段。 $ unwind 通过为嵌入文档创建新文档(在您的情况下为品质)来实现更好的嵌套搜索。
但如果你将 $ unwind 作为第一阶段,它会通过展开不必要的文件来创造性能开销。 更好的方法是将 $ match 作为聚合管道的第一个阶段。
现在,聚合查询的速度有多快: 聚合查询的速度取决于存储在嵌入式文档中的数据量。如果将100万个条目存储到嵌入式doc 质量中,它将在展开数百万个条目时产生性能开销。
因此,这一切都取决于您如何创建数据库架构。此外,为了加快查询速度,您可以查看mongodb的multi key indexing和sharding方法。