Mongoose:如何避免重复文件?

Posted

技术标签:

【中文标题】Mongoose:如何避免重复文件?【英文标题】:Mongoose: how to avoid duplicating documents? 【发布时间】:2016-07-24 15:00:37 【问题描述】:

我为一些评论设计了一个集合。 评论集合架构包含帖子和主题。 帖子属性(键、电话、日期、内容、作者姓名)是评论集合的直接子级。 主题属性(键、标题)是主题对象的子对象,它是评论集合的子对象。 每个帖子都属于一个主题。 每个帖子键都是唯一的,每个主题键都是唯一的。 如果许多帖子属于一个主题,则每个评论都会重复主题数据(NoSQL 不是 ACID,对吧?:-)

问题是:复制主题属性的决定是否正确,或者我应该为帖子和主题使用不同的集合?

这是我的模型:

var reviewSchema = new mongoose.Schema(
  key: String,
  phone: String,
  date: Date,
  contents: String,
  author: 
    name: String,
  ,
  topic: 
    key: String,
    title: String,
  ,
);
reviewSchema.index( 'key': 1 ,  unique: true );
reviewSchema.index( 'phone': 1 ,  unique: false );
reviewSchema.index( 'topic.key': 1 ,  unique: false );

【问题讨论】:

【参考方案1】:

如果您希望避免重复,请为 Topic 创建单独的架构,然后在您的 Reviews 中引用它:

var TopicSchema = new mongoose.Schema(
    key: String,
    title: String
);

var ReviewSchema = new mongoose.Schema(
    key: String,
    phone: String,
    ...
    topic: type: Schema.Types.ObjectId, ref: 'Topic'
);

var Topic = mongoose.model('Topic', TopicSchema);
var Review = mongoose.model('Review', ReviewSchema);

从这里,当您想插入带有TopicReview 作为子文档时,使用populate() method。基于您将 author 存储在其自己的文档中这一事实,您可以考虑在其中遵循相同的模式。

我很好奇您使用key。默认情况下,MongoDB 在***文档上创建一个唯一的_id,这是一种主键。如果这是您对 key 的意图,您可能应该让 MongoDB 处理它。

但归根结底,您的问题没有“正确”的解决方案,只有权衡比较。 MongoDB 的一个优点是能够轻松地“存储您查询的内容”,并且由于 Topics 非常小,如果您每次获取评论时都需要主题,则可能值得重复。 MongoDB 不是集合中的 ACID(我不能代表其他 NoSQL 选项),因此使用这种方法,一次更新所有嵌入式主题可能会给用户带来短暂的差异。

// Get entire review in one go, including subdocuments!
Review.findOne(  "key": "myReview" , (err, doc) =>  /* do things */  );

// On bulk topic updates, not all topics change at once (not ACIDic)
Review.update(
   topic.title: 'foo' ,
   topic.title: 'bar' ,
   multi: true ,
  (err, doc) => /* callback */ 
);

如果您来自 SQL 背景,上面描述的populate() 范式会感觉更舒服。而且由于 MongoDB 对每个文档都是 ACIDic,因此更新一次主题对于引用它的所有其他文档就足够了。在幕后,这将需要 Mongoose 至少进行两次查询:一次查询Review,然后再次查询引用的Topic

// To replace refs with documents two queries behind the scenes
Review.findOne(  key: 'myReview'  )
  .populate('topic').exec( (err, review) =>  /* do things */ )

// But updating a single topic is ACIDic, since reviews only contain references
Topic.update(  key: 'foo' ,  title: 'sci-fi' , (err, res) => /* more stuff */  )

根据我的经验,除非您将查询管道推到极限并希望不惜一切代价缩短响应时间,否则使用 populate() 的单独架构值得额外查询的权衡。

【讨论】:

谢谢!确保此类数据的重复是可以接受的,这对我来说很重要...... :-) 绝对!如果有帮助,请采纳答案。 再等几天以获得更完整的答案... :-)

以上是关于Mongoose:如何避免重复文件?的主要内容,如果未能解决你的问题,请参考以下文章

mongoose的基本操作

mongoose基本增删改查

如何在nodejs中将猫鼬模型数据作为数组返回[重复]

NodeJS Express Mongoose 返回空 []

nestjs mongoose .insertMany 不是函数

Moogose的基本连接以及增删改查操作