【发布时间】:2019-06-11 05:21:29
【问题描述】:
我正在尝试将一个对象推送到一个数组中,并且每个对象都有一个名为 name 的属性,该属性应该是唯一的
这是我的 mongodb 架构:
db.createCollection("users", {
validator: {
$jsonSchema: {
bsonType: "object",
required: ["nickname", "email", "password", "salt"],
properties: {
nickname: {
bsonType: "string",
description: "must be a string and is required"
},
password: {
bsonType: "string",
description: "must be a string and is required"
},
email: {
pattern: "^[^@\s]+@[^@\s]+\.[^@\.\s]+$",
bsonType: "string",
description: "must be a valid email and is required"
},
salt: {
bsonType: "string",
description: "must be a string and is required"
},
characters: {
bsonType: "array",
required: [
"name",
"head",
"class",
"race",
"genre",
"agility",
"charisma",
"constitution",
"inteligence",
"strength",
"level"
],
properties: {
name: {
bsonType: "string",
description: "must be a string and is required"
},
description: {
bsonType: "string",
description: "must be a string and is required"
},
head: {
bsonType: "int",
description: "must be a integer and is required"
},
class: {
bsonType: "string",
description: "must be a string and is required"
},
race: {
bsonType: "string",
description: "must be a string and is required"
},
genre: {
bsonType: "string",
description: "must be a string and is required"
},
agility: {
bsonType: "int",
description: "must be a integer and is required"
},
charisma: {
bsonType: "int",
description: "must be a integer and is required"
},
constitution: {
bsonType: "int",
description: "must be a integer and is required"
},
intelligence: {
bsonType: "int",
description: "must be a integer and is required"
},
strength: {
bsonType: "int",
description: "must be a integer and is required"
},
"time-online": {
bsonType: "int",
description: "must be a integer and is required"
},
gold: {
bsonType: "int",
description: "must be a integer and is required"
},
level: {
bsonType: "int",
description: "must be a integer and is required"
},
"experience-obtained": {
bsonType: "int",
description: "must be a integer and is required"
},
"experience-for-next-level": {
bsonType: "int",
description: "must be a integer and is required"
},
online: {
type: "boolean",
description: "must be a boolean and is required"
},
"home-town": {
bsonType: "string",
description: "must be a string and is required"
},
items: {
bsonType: "array",
required: ["id", "quantity"],
properties: {
"id": {
bsonType: "int",
description: "must be a integer and is required"
},
"quantity": {
bsonType: "int",
description: "must be a integer and is required"
}
}
},
position: {
bsonType: "object",
required: ["position-x", "position-y", "map"],
properties: {
"position-x": {
bsonType: "int",
description: "must be a integer and is required"
},
"position-y": {
bsonType: "int",
description: "must be a integer and is required"
},
"map": {
bsonType: "int",
description: "must be a integer and is required"
}
}
},
deaths: {
bsonType: "object",
required: ['characters', 'npcs'],
properties: {
characters: {
bsonType: "int",
description: "must be a integer and is required"
},
npcs: {
bsonType: "int",
description: "must be a integer and is required"
}
}
}
}
}
}
}
}
})
db.users.createIndex({ email: 1 }, { unique: true })
db.users.createIndex({ nickname: 1 }, { unique: true })
db.users.createIndex({ "characters.name": 1 }, { unique: true })
正如您在最后一行中看到的那样,我正在尝试将 characters.name 设置为唯一但适用于其他文件,但对于同一个文件不起作用,因为我可以创建许多 @ 987654326@同名
这是我的操作(我用mongojs)
mongodb.users.findAndModify({
query: {
email: req.body.email,
},
update: {
$push: { characters: newCharacter }
},
new: true
}, function (error, user, lastErrorObject) {
if (error) return res.status(500).json(error)
if (!user) {
return res.status(500).send("No existe el usuario con el email: " + req.body.email)
}
console.info("Se creo un nuevo personaje con el nombre: " + req.body.name)
return res.status(200).json(user)
})
这是我得到的回应:
{
"_id": "5cfda33d0c1ceea5196afd93",
"nickname": "juancito2",
"password": "4e523cf0d1ff0cc6a372e22d04b7735efbcf01a19bca1843ac6b9046e8b62108",
"email": "a@a.a2",
"salt": "kZFsK0s+ehyXA9GOWn+ehw==",
"characters": [
{
"name": "recox1",
"description": "un pj poderoso",
"head": 1,
"class": "Warrior",
"race": "Elf",
"genre": "Male",
"agility": 10,
"charisma": 11,
"constitution": 12,
"intelligence": 13,
"strength": 14,
"gold": 200,
"level": 1
},
{
"name": "recox1",
"description": "un pj poderoso",
"head": 1,
"class": "Warrior",
"race": "Elf",
"genre": "Male",
"agility": 10,
"charisma": 11,
"constitution": 12,
"intelligence": 13,
"strength": 14,
"gold": 200,
"level": 1
},
}
我做错了什么?我需要做什么来实现我的目标?我阅读了这些文件,但没有运气。
https://docs.mongodb.com/manual/core/index-unique/
https://docs.mongodb.com/manual/core/index-compound/#index-type-compound
https://docs.mongodb.com/manual/core/index-multikey/#multikey-indexes
【问题讨论】:
-
你能检查索引是用
unique选项使用db.users.getIndexes()创建的吗?使用db.users.createIndex({ "characters.name": 1 }, { unique: true })将您的问题减少到最少的复制,我无法插入多个同名字符。例如:db.users.insert({characters: { name: 'Bobby' }}). -
据我所知,我们可以为同一个文件设置唯一索引,与其他用户一起工作正常,就像你上面提到的那样。现在我想弄清楚如何才能确保我在数组中有一个具有属性名称的对象
-
请编辑您的问题以包含一个未按预期验证的示例文档以及您尝试运行的插入或更新操作。
-
@Stennie 完成,我修改了问题
-
谢谢 - 示例文档非常有帮助。唯一索引约束适用于separate documents in the collection,因此这确实允许在同一文档中的数组内重复。对于您当前的架构,我不确定服务器是否有一种直接的方法来评估嵌入式数组中单个字段的唯一性,因此您可能必须在客户端逻辑中进行评估或使用单独的字符集合。