Mongodb很多很多关系

时间:2015-12-19 16:44:34

标签: node.js mongodb mongoose

我正在开发一个基于mean.js的webapp,部分应用程序是带有标签的项目,类似于每个博客条目都有标签的博客网站。

我到处寻找一个很好的例子/教程,解释使用mongodb / mongoose创建多对多关系的最佳方法,但我似乎无法找到任何东西。

每个项目都可以有多个标签,我希望用户能够找到具有特定标签的所有项目。

我非常感谢有关正确方法的任何建议/示例。 TIA

3 个答案:

答案 0 :(得分:3)

在两个集合中保留一组id。例如:

coll1:

{
  _id: ObjectId("56784ac717e12e59d600688a"),
  coll2_ids: [ObjectId("..."), ObjectId("..."), ObjectId("..."), ...]
}

coll2:

{
  _id: ObjectId("56784ac717e12e59d600677b"),
  coll1_ids: [ObjectId("..."), ObjectId("..."), ObjectId("..."), ...]
}

这种方法的优点是,当您从任一集合中获得文档时,只需执行

即可立即从相反的集合中提取所有相关文档。
obj = db.coll1.findOne({})
db.coll2.find({_id: {$in: obj['coll2_ids']}}) # returns all associated documents

反之亦然。

答案 1 :(得分:1)

对于多对多关系,我发现mongoose-relationship非常有用。

以下是使用mongoose-relationship模块解决问题的示例:

// In TagsModel.js file ----------------------------------------------
var mongoose = require('mongoose');
var schema = mongoose.Schema;
var relationship = require("mongoose-relationship");

var tagSchema = new schema({
   projects: [{
      type: mongoose.Schema.Types.ObjectId,
      ref: 'Project',
      childPath: 'tags'
   }],
   ....
});

tagSchema.plugin(relationship, {
     relationshipPathName: 'projects'
});
var tagModel = mongoose.model('Tag', tagSchema);
--------------------------------------------------------------------

// In ProjectModel.js file -----------------------------------------
var mongoose = require('mongoose');
var schema = mongoose.Schema;

var Projects = new Schema({
    tags : [{
         type: mongoose.Schema.Types.ObjectId,
         ref: 'Tag'
         }],
    ...
});
var tagModel = mongoose.model('Project', tagSchema);

使用此模型结构,您将能够按项目按特定标记和标记查找项目。

答案 2 :(得分:0)

您似乎只想在Project架构中拥有一个标记数组。

var Tags = new Schema({
    name : String
});

var Projects = new Schema({
    tags : [String] // When you save a Tag just save the Name of it here
});

// This way you could easily look it up
// Assuming "name" was passed in as a param to express

Projects.find({ 'tags' : req.params.name }) // voila!

还有其他方法(例如保存ObjectIds)。 如果您认为标记名称可能经常更改,则此方法会更容易,但如果标记被“删除”,则必须再次查看所有项目以删除该ObjectId

tags : [{ type: Schema.ObjectId, ref : 'Tags' }]

基本上,这就是你要在项目模型中的“标签”数组中保存一个String或ObjectId引用(名称)。

记住当你要编辑标签名称/删除标签/等时,你会想要通过并更新(如果它们被保存为字符串)/从任何项目中删除这些标签阵列。