在我的电影模式中,我有一个“ release_date”字段,可以包含嵌套的子文档。
这些子文档包含三个字段:
我需要确保前两个字段是唯一的(主键)。
我首先尝试设置一个唯一索引。但是我终于意识到,MongoDB不支持子文档上的唯一索引。 索引已创建,但是验证不会触发,我仍然可以添加重复项。
然后,我尝试修改我的更新功能以防止重复,如本文所述(请参阅替代方法):http://joegornick.com/2012/10/25/mongodb-unique-indexes-on-single-embedded-documents/
$ ne效果很好,但就我而言,我将两个字段组合在一起,而且这是一种更加复杂的方式...
$ addToSet很不错,但不是我要搜索的内容,因为“详细信息”字段可能不是唯一的。
我还尝试了像mongoose-unique-validator这样的插件,但是它不适用于子文档...
我最终遇到了两个查询。一个用于搜索现有子文档,如果先前的查询未返回任何文档,则另一个用于添加子文档。
insertReleaseDate: async(root, args) => {
const { movieId, fields } = args
// Searching for an existing primary key
const document = await Movie.find(
{
_id: movieId,
release_date: {
$elemMatch: {
country_code: fields.country_code,
date: fields.date
}
}
}
)
if (document.length > 0) {
throw new Error('Duplicate error')
}
// Updating the document
const response = await Movie.updateOne(
{ _id: movieId },
{ $push: { release_date: fields } }
)
return response
}
这段代码可以正常工作,但我宁愿只使用一个查询。
有什么主意吗?我不明白为什么它这么复杂,应该经常使用。
答案 0 :(得分:0)
感谢RichieK的回答!效果很好。
请小心将字段名放在“ $ not”之前,如下所示:
insertReleaseDate: async(root, args) => {
const { movieId, fields } = args
const response = await Movie.updateOne(
{
_id: movieId,
release_date: {
$not: {
$elemMatch: {
country_code: fields.country_code,
date: fields.date
}
}
}
},
{ $push: { release_date: fields } }
)
return formatResponse(response, movieId)
}
非常感谢!