使用空子文档集合保存Mongoose文档会导致重复键错误

时间:2022-12-02 02:34:22

I have two mongoose schemas:

我有两个猫鼬模式:

var productSchema = new Schema({
    name: { type: String, required: true, unique: true },
    ...
});
...
var categorySchema = new Schema({
    ...
    products: [ProductSchema]
});

When I try to save categories

当我尝试保存类别时

var categories = [
    {..., products: []},
    {..., products: []}
];

or even without products

甚至没有产品

var categories = [
    {...},
    {...}
];

I'm getting error

我收到了错误

{ [MongoError: E11000 duplicate key error index: test.categories.$products.name_1  dup      key: { : undefined }]
name: 'MongoError',
err: 'E11000 duplicate key error index: test.categories.$products.name_1  dup key: { : undefined }',
 code: 11000,
 n: 0,
 lastOp: { _bsontype: 'Timestamp', low_: 6, high_: 1404282198 },
 ok: 1 }

It seems like mongoose is trying to save products with undefind names.

似乎mongoose正试图用不寻常的名字来保存产品。

Mongoose log before getting error:

收到错误之前的Mongoose日志:

Mongoose: categories.insert({ __v: 0, products: [], _id: ObjectId("53b3c167d28a86102dec420a"), order: 1, description: 'Category 1', name: 'Cat 1' }) {}  
Mongoose: categories.insert({ __v: 0, products: [], _id: ObjectId("53b3c167d28a86102dec420b"), order: 2, description: 'Category 2', name: 'Cat 2' }) {}  

If I remove unique: true from the name property of productSchema two categories are added with empty products [] collections.

如果我从productSchema的name属性中删除unique:true,则会使用空products []集合添加两个类别。

What am I doing wrong?

我究竟做错了什么?

Thank you!

1 个解决方案

#1


10  

This is pretty normal really. The empty array is essentially considered to be a "null" value for the "products.name" field, that of course violates the unique constraint on the index.

这真的很正常。空数组基本上被认为是“products.name”字段的“null”值,这当然违反了索引的唯一约束。

You could essentially "skip" any values of "name" that are in fact undefined, and you do this by adding the "sparse" property to the index. In the present schema path form:

您实际上可以“跳过”实际上未定义的“name”的任何值,并且您可以通过向索引添加“sparse”属性来实现此目的。在当前架构路径形式中:

var productSchema = new Schema({
  name: { type: String, required: true, unique: true, sparse: true }
});

var categorySchema = new Schema({
  products: [productSchema]
});

Now as long as there is no value in "name" there will be no problem unless of course it actually exists somewhere. Make sure to drop the index already created first though.

现在,只要“名称”中没有值,就没有问题,除非它实际上存在于某个地方。确保首先删除已创建的索引。

Just a note, be aware that what this is doing is making sure that the "products.name" values are unique for the "whole" collection. If you are just trying to make sure they are unique for a given category, then indexing is not your solution and you need to ensure that by other means.

请注意,请注意这样做是为了确保“products.name”值对于“整个”集合是唯一的。如果您只是想确保它们对于给定类别是唯一的,那么索引不是您的解决方案,您需要通过其他方式确保。

#1


10  

This is pretty normal really. The empty array is essentially considered to be a "null" value for the "products.name" field, that of course violates the unique constraint on the index.

这真的很正常。空数组基本上被认为是“products.name”字段的“null”值,这当然违反了索引的唯一约束。

You could essentially "skip" any values of "name" that are in fact undefined, and you do this by adding the "sparse" property to the index. In the present schema path form:

您实际上可以“跳过”实际上未定义的“name”的任何值,并且您可以通过向索引添加“sparse”属性来实现此目的。在当前架构路径形式中:

var productSchema = new Schema({
  name: { type: String, required: true, unique: true, sparse: true }
});

var categorySchema = new Schema({
  products: [productSchema]
});

Now as long as there is no value in "name" there will be no problem unless of course it actually exists somewhere. Make sure to drop the index already created first though.

现在,只要“名称”中没有值,就没有问题,除非它实际上存在于某个地方。确保首先删除已创建的索引。

Just a note, be aware that what this is doing is making sure that the "products.name" values are unique for the "whole" collection. If you are just trying to make sure they are unique for a given category, then indexing is not your solution and you need to ensure that by other means.

请注意,请注意这样做是为了确保“products.name”值对于“整个”集合是唯一的。如果您只是想确保它们对于给定类别是唯一的,那么索引不是您的解决方案,您需要通过其他方式确保。