2013-04-02 71 views
2

我有这两个简化的模式,我想“加入”基于IP地址。猫鼬 - 填充其他然后编号

var personSchema = Schema({ 
    name: String, 
    ip: String 
}); 

var logSchema = Schema({ 
    message: String, 
    ip: String 
}); 

它会工作,如果person._id是IP地址。但这不适合我。

目前我已经解决了这个问题,当新的日志被保存时,我搜索该人并添加对日志的引用。架构是那么这样的:

var logSchema = Schema({ 
    message: String, 
    ip: String, 
    person: { type: Schema.Types.ObjectId, ref: 'Person' } 
}); 

我读过猫鼬Populate文档,Document#populatedModel.populate()。我仍然不确定是否有可能。这个例子非常简单,我使用mapReduce和日志收集分组,因此人口对我来说会很好。

我也读过Database references在我看来,唯一的选择是基于_id填充。但它是纯粹的mongodb,也许有另一种可能性使用猫鼬?

是否有可能填充不基于_id字段的查询?

回答

0

MongoDB不支持连接。所以.populate只是另一个查询,因此最好的解决方案是手动进行另一个查询。

+0

千万要填写您认为最好再进行一次查询,然后在每个日志记录中保存人员引用? –

+0

@ Mr.Pohoda它并没有真正帮助你,因为你仍然必须做一个单独的查询('.populate'为你做)。维护这种数据库结构将会更困难。也许我还不够清楚:使用'.populate'做一个单独的查询**而不是**。 – freakish

+0

为什么填充使用较少的内存然后findOne?我刚刚查询了20万个条目(更大更容易看出差异),而使用填充时我的mongod进程永远不会超过23%,但是当我使用findOne属性时,它几乎可以达到cpu的100%? – Snymax

0

MongoDB 3.2引入了$ lookup聚合。你也可以在猫鼬身上使用它。这是一个如何使用条件find也使用它的一个例子:

Log.aggregate(
     { $match: {log_property: 'value'}}, 
     { $lookup: {from: 'person', localField: 'ip', foreignField: 'ip', as: 'user'} } 
    ).exec(function (err, logs) { 
     if (err) { 
     next(err); 
     } 

     res.json(logs); 
    } 
); 

在上面的例子中,每个日志user属性将与人从匹配Person模型文件