mongoose 多对多查询
发布于 10 年前 作者 p412726700 10133 次浏览 最后一次编辑是 8 年前 来自 问答

如题 现在有三个 Schema Article

var ArticleSchema = new Schema({
  title: {type: String},
  content: {type: String},
  source: {type: String},
  top: {type: Boolean, default: false},
  created_at: {type: Date, default: Date.now},
  updated_at: {type: Date, default: Date.now},
  views: {type: Number, default: 0},
  comments: {type: Number, default: 0},
  cat: {type: Number}
}, {
  toJSON: {virtuals: true}
});

Tag

var TagSchema = new Schema({
  _id: {
    type: String,
    unique: true,
    default: shortId.generate
  },
  name: {type: String}
});

TagMap

var TagMapSchema = new Schema({
  _id: {
    type: String,
    unique: true,
    default: shortId.generate
  },
  article_id: {type: String},
  tag_id: {type: String}
});

想要实现通过Tag查询到文章,并且文章也能查询到包含的Tag

10 回复

看看这样是否可以,直接在 ArticleSchema 里增加 tags: [Schema.Types.ObjectId] ,直接往里面存tag._id!

@54sword 存ID的话

Article.find({},function(err, articles) {
  if (err) {
    return Handlerror(res, err)
  }
  articles.forEach(function(article) {
    Tag.find({
      _id: {
        $in: article.tags
      }
    },
    function(err, tags) {
      article.tags = tags; //这行代码无效 无法把找到对应的tags赋值给article.tags
    })
  })
})

@p412726700 可以这样,在 ArticleSchema 增加 tags: [{ type: Schema.Types.ObjectId, ref: ‘Tag’ }] 取数据的时候这样, Article.find({}).populate(‘tags’).exec(callback); 这样就直接可以从tag表中找出对应得tag._id数据,放到查询结果中了。

这里需要注意的是:ref的 Tag 对应的是 mongoose.model(‘Tag’, TagSchema); 的名称

@54sword 如果用ref的话 集合是这样的吧

var ArticleSchema = new Schema({
  title: {type: String},
  content: {type: String},
  source: {type: String},
  top: {type: Boolean, default: false},
  created_at: {type: Date, default: Date.now},
  updated_at: {type: Date, default: Date.now},
  views: {type: Number, default: 0},
  comments: {type: Number, default: 0},
  cat: {type: Number},
  tags: [{ type: Schema.Types.ObjectId, ref: ‘Tag’ }]
}, {
  toJSON: {virtuals: true}
});

var TagSchema = new Schema({
  _id: {
    type: String,
    unique: true,
    default: shortId.generate
  },
  articles: [{ type: Schema.Types.ObjectId, ref: ‘Article'
  name: {type: String}
});

假如是这样的话 当我创建一篇文章

Article.create({
  req.body
},
function(err, article) {
  if (err) return Handlerr(res, err);
  var tagIds = req.body.tags.map(function(tag) {
    return tag.id
  });
  Tag.find({
    _id: {
      $in: tagIds
    }
  },
  function(err, tags) {
    //到这里之后 我怎么 把获得的 tags标签 插入到article.tags?
    //用article.push?
  })
})

article.tags.push(); 就可以,和JS数组的操作方式一样。 操作完以后,article.save(); 一下就保存了

@p412726700 TagSchema 这里的 articles: [{ type: Schema.Types.ObjectId, ref: ‘Article’}] 你是想通过tag._id查询文章是吗 你这个方式应该也是可以的, 也可以试一试这个方式,用tag._id到Article表里面查询,查询条件针对tags里面的id就可以了, 这样可以根据文章的时间排序以及查询指定数量的文章。

@54sword 用mongodb做关联查询 简直要疯了

@p412726700 哈哈!你的一篇文章是只有一个标签还是多个标签?

tag集合加一个articleId不就行了吗

回到顶部