搜索嵌入文档Mongoose + nodejs

时间:2011-06-01 11:24:08

标签: mongodb node.js mongoose

我是Mongoose的新手,我在搜索方面遇到了问题。

这些是我的架构:

var CommentSchema = new Schema({
    body       : String
  , comments   : [CommentSchema]
});

var PostSchema = new Schema({
    body        : String
  , comments    : [CommentSchema]
});

有很深的评论嵌套。当有人回答现有评论时,我该如何找到?

2 个答案:

答案 0 :(得分:0)

你可以看一下github上的mongoose测试套件。

model_querying_test

以下是您要找的内容:

基于嵌入式文档字段的测试查找:

function () {
    var db = start(), BlogPostB = db.model('BlogPostB', collection);

    BlogPostB.create({comments: [{title: 'i should be queryable'}]}, function (err, created) {
      should.strictEqual(err, null);
      BlogPostB.findOne({'comments.title': 'i should be queryable'}, function (err, found) {
        should.strictEqual(err, null);
        found._id.should.eql(created._id);
        db.close();
      });
    });
    },

答案 1 :(得分:0)

对此的一个解决方案是将注释存储为单独的模型,您可以直接查询,并存储对相关的ObjectIds和注释与帖子之间路径的引用。

在Mongoose相关文档中使用Populate功能可以与嵌入式文档类似地运行,尽管在查询它们的方式上存在一些重要差异,并且您必须更加谨慎地保持填充关系。

像这样设置:

var mongoose = require('mongoose')
  , Schema = mongoose.Schema
  , ObjectId = Schema.Types.ObjectId;

var PostsSchema = new Schema({
  body     : String,
  stories  : [{ type: ObjectId, ref: 'Story' }]
});

var CommentsSchema = new Schema({
  body     : String,
  post     : { type: ObjectId, ref: 'Post' },
  comments : [{ type: ObjectId, ref: 'Comment' }]
});

var Story   = mongoose.model('Post', PostsSchema);
var Comment = mongoose.model('Comment', CommentsSchema);

如果你这样做,它需要更多的查询来获取帖子及其所有评论(这将比使用单个查询加载帖子及其完整的评论层次更慢)但是你将能够直接查询注释并检索它们的发布(但在嵌套时不容易找到注释的完整路径)。

这些都是权衡取舍;应该在应用程序及其预期使用模式的上下文中做出最佳决策(递归搜索注释,或者单独存储它们然后递归加载它们)。

另一个警告; populate功能目前仅限于单级链接的ObjectIds;您必须在返回的每个注释上调用它以获取完整的嵌套数据集。有几个插件可以帮助解决这个问题,例如mongoose-subpopulate,很快就会在Mongoose本地支持它 - 请参阅github issue here