在Mongoose中存储不同类型的ObjectsIds

时间:2014-03-28 17:44:17

标签: node.js mongodb mongoose

如何在单个参考数组中引用多个不同类型的ObjectId

鉴于下面的简单架构:

var Schema = mongoose.Schema;

var AddressSchema = new Schema({
  value: String
});

var AddressRangeSchema = new Schema({
  from: String,
  to: String
});

var AddressListSchema = new Schema({
  name: String,
  list: [Schema.Types.ObjectId]
});

AddressList.list可由任意数量的AddressAddressRangeAddressList组成。如下:

var firstAddr = new Address({
  value: "172.0.0.1"
});

var firstAddrRange = new AddressRange({
  from: "172.0.0.10",
  to: "172.0.0.20"
})

var firstList = new AddressList({
  name: "MyFirstList",
  list: [
    firstAddr.id,
    firstAddrRange.id
  ]
});

如果它们是三种可能类型中的一种,我如何拉出list数组中的对象?

1 个答案:

答案 0 :(得分:0)

使用Mongodb,一次只能查询一个集合。像Mongoose这样的ORM层可能会为您抽象,但最终您要为每个集合执行单独的查询。

如果列表中项目的顺序并不重要,则整个操作变得更加简单。如果订单很重要,那么您将需要做更多的工作。

选项1) 查询每个集合的所有ID。你最多可以传递16MB!在$ in查询中的id值,所以即使对于大量的集合也是如此。

AddressSchema.find({_id:{$in:allIds} }, callback);
AddressRangeSchema.find({_id:{$in:allIds} }, callback);

这将为您提供所有项目,然后您可以手动浏览并将它们合并到正确的顺序中。对于小套件(低于100),这可能不是一个糟糕的选择。您正在对_id字段进行索引,因此缓存命中和未命中非常便宜。

选项2) 存储元数据以及指示集合的_id:

var AddressListSchema = new Schema({
  name: String,
  list: [{type:String, _id: Schema.Types.ObjectId}]
});

var firstList = new AddressList({
  name: "MyFirstList",
  list: [
    {type:'a', _id: firstAddr.id},
    {type:'ar',_id: firstAddrRange.id}
  ]
});

然后,您可以正确查询每个集合。这将减少缓存未命中数,但会增加AddressList集合中存储数据的大小。如果您要在部分视图中缓存和显示名称或其他字段,则此模式特别有用。

选项3)更改架构以嵌套所有数据

不确定您的用例,但嵌套架构而不是拥有三个单独的集合可能是最好的选择。