我已经获得了大约300,000张照片的MongoDB元数据数据库。每个都有一个本机唯一ID,需要是唯一的,以防止重复插入。它还有一个时间戳。
我经常需要运行汇总查询才能查看每天有多少张照片,因此我还有一个{YYYY-MM-DD格式的date
字段。这显然不是唯一的。
现在我只在id
属性上有一个索引,就像这样(使用Node驱动程序):
collection.ensureIndex(
{ id:1 },
{ unique:true, dropDups: true },
function(err, indexName) { /* etc etc */ }
);
按照日期获取照片的群组查询需要相当长的时间,可以想象:
collection.group(
{ date: 1 },
{},
{ count: 0 },
function ( curr, result ) {
result.count++;
},
function(err, grouped) { /* etc etc */ }
);
我已经阅读了索引策略,我认为我还需要索引date
属性。但是我当然不想让它变得独一无二(尽管我认为将它与独特的id结合起来是独一无二的)。我应该使用常规复合索引,还是可以链接.ensureIndex()
函数并仅指定id
字段的唯一性?
答案 0 :(得分:2)
MongoDB没有“混合”类型索引,这些索引可以是部分唯一的。另一方面,如果可能,为什么不使用_id
而不是id
字段。根据定义,它已被索引并且是唯一的,因此它将阻止您插入重复项。
Mongo只能在查询子句中使用单个索引 - 在创建索引时需要考虑。对于这个特定的查询和要求,我建议在id字段上有一个单独的唯一索引,如果你使用_id
,你会得到它。此外,您只能在日期字段上创建非唯一索引。如果你运行这样的查询:
db.collection.find({"date": "01/02/2013"}).count();
Mongo将只能使用索引来回答查询(覆盖索引查询),这是您可以获得的最佳性能。
请注意,如果仅按日期搜索,Mongo将无法在(id,date)上使用复合索引。您查询必须首先匹配索引前缀,即如果您按id搜索,则可以使用(id,date)索引。
答案 1 :(得分:0)
另一种选择是在模式本身中预先聚合。无论何时插入照片,都可以增加此计数器。这样您就不需要运行任何聚合作业。您还可以运行一些测试来确定此方法是否比聚合更具性能。