索引多个MongoDB字段,只使一个唯一

时间:2014-01-31 15:23:46

标签: node.js mongodb indexing database

我已经获得了大约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字段的唯一性?

2 个答案:

答案 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)

另一种选择是在模式本身中预先聚合。无论何时插入照片,都可以增加此计数器。这样您就不需要运行任何聚合作业。您还可以运行一些测试来确定此方法是否比聚合更具性能。