我正在尝试将一个对象推入数组,并且每个对象都有一个名为 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 设置为唯一,但适用于其他文件,但是对于同一文件却无法使用,因为我可以创建许多{ {1}}同名
这是我的手术(我使用characters
)
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)
})
我做错了什么?我需要做什么才能实现自己的目标?我读了这些文件,但没有运气。
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
答案 0 :(得分:0)
最后,我最终在client
端进行了验证,因为mongodb不允许同一文件的数组唯一,如果将来有人发现更好的方法,我会很高兴的>
//As in MongoDB we can't or i don't know how to perform this in one action
//First we do a query to get the user account and then I check if there is an user with that name in the account
//Then we perform a second query to save the character in case it doesn't exist
//Because if I don't do this verification I can repeate the character.name inside the user
//Even if "characters.name" is an index.
mongodb.users.findOne({
email: req.body.email
}, function (error, user) {
if (error) return res.status(500).json(error)
if (!user) return res.status(409).send("No existe un usuario con el email: " + req.body.email)
//Verify if the character.name is already in the user account
if (user && user.characters) {
const isCharacterInUser = user.characters.find(el => el.name === req.body.name);
if (isCharacterInUser) return res.status(409).send("Ya existe un personaje con ese nombre en esta cuenta " + req.body.name)
}
//If the account does not have any character, initalize the array
user.characters = user.characters ? user.characters : [];
user.characters.push(newCharacter)
mongodb.users.save(user, function(error, doc) {
if (error && error.code === 11000) return res.status(409).send("Ya existe un personaje con ese nombre")
if (error) return res.status(500).json(error)
return res.status(200).json(doc)
})
})