MongoDB: 处理自动增加模型标识符而不是您自己的模型标识符 ObjectID 芒果

由于管理解决方案,我们使用 userId 对于用户集合, postId 用于收集消息和 topicId 收集主题 '_id' 每个集合作为唯一标识符。

它在工作开始时导致几个问题。 - 我遇到的一个问题是相关的 upserts -

使用 Mongoose, 我们有一个限制的计划 userId 对于独特的意思 - 但是当您在用户模型上进行更新时,使用更新和插入 true ,

MongoDB, 看来只是看看 ObjectIds 收藏,看它是否存在 - 它不是检查模型是否存在相同的模型 userId - 因此,蒙特加插入而不是更新。

让我用一些数据来说明它:

假设用户的集合有一个文档:


{
_id:'561b0fad638e99481ab6d84a'
userId:3,
name:'foo'
}


然后我们跑:


User.update/{userId:3},{"$set":{name:'bar'},{upsert:true},function/err,resp/{

if/err/{

// "errMessage": "insertDocument :: caused by :: 11000 E11000 duplicate key error index: app42153482.users.$userId_1 dup key: { : 3 }",
}

}/;


有可能思考 MongoDB 会找到现有文件 userId:3 和 udpate 他,所以必须有一些我做错了什么,因为他给了我一个重复键的错误?
已邀请:

莫问

赞同来自:

通常是默认值 ObjectId 更适合 _id. 在此,在这种情况下,您可以覆盖默认值 _id, 要么有自己的领域 id/例如, userId 在你的情况下/.

用单独使用

柜台集合

跟踪最后使用的数字序列。 场地

_id

包含序列的名称和字段

seq

- 序列的最后一个值。

插入B.

柜台集合

用户ID的初始值:


db.counters.insert/ {
_id: "userid",
seq: 0 } /


创建

功能 getNextSequence, 接受序列名称。 功能使用

方法 findAndModify// 原子增加值

seq

并返回这个新含义:


function getNextSequence/name/ {
var ret = db.counters.findAndModify/
{
query: { _id: name },
update: { $inc: { seq: 1 } },
new: true
}
/;

return ret.seq;
}


使用此功能

getNextSequence//

期间

insert//

.


db.users.insert/
{
_id: getNextSequence/"userid"/,
name: "Sarah C."
}
/

db.users.insert/
{
_id: getNextSequence/"userid"/,
name: "Bob D."
}
/


因此,在同一计数器中,您可以根据需要维护这么多的序列。 解决问题 upsert 看看街区

乐观周期

在这个链接中
https://docs.mongodb.org/manua ... ield/
.

第二种方法是使用中间软件。 mongoose, 如
https://github.com/TheRoSS/mongodb-autoincrement
.

我希望它会有所帮助。

快网

赞同来自:

我不知道哪个版本 MongoDB 和 Mongoose 你使用,但我无法重现你的问题 MongoDB 3.0 和 Mongoose 4.1.10.

我为您制作了一个样本,它将创建和保存新用户,将更新它 /使用 upsert/ 并创建另一个 upsert. 尝试启动此代码:


"use strict";
var mongoose=require/"mongoose"/;
var Schema = require/'mongoose'/.Schema;
var ObjectId = mongoose.Schema.Types.ObjectId;

// Connect to test
mongoose.connect/"mongodb://localhost:27017/test"/;

// Lets create your schema
var userSchema = new Schema/{
_id: ObjectId,
userId: {type: Number, unique: true },
name: String
}/;

var User = mongoose.model/"User", userSchema, "Users"/;


User.remove// // Let's prune our collection to start clean
.then/ function// {
// Create our sample record
var myUser = new User/{
_id:'561b0fad638e99481ab6d84a',
userId:3,
name:'foo'
}/;

return myUser.save//;
}/
.then/ function// {
// Now its time to update /upsert userId 3/
return User.update/{userId:3},{"$set":{name:'bar'}},{upsert:true}/;
}/
.then/ function// {
// Now its time to insert /upsert userId 4/
return User.update/{userId:4},{"$set":{name:'bee'}},{upsert:true}/;
}/
.then/ function// {
// Lets show what we have inserted
return User.find//.then/function/data/ {console.log/data/}/;
}/
.catch/ function/err/ {
// Show errors if anything goes wrong
console.error/"ERROR", err/;
}/
.then/ function// {
mongoose.disconnect//;
}/;

八刀丁二

赞同来自:

遵循文件 /的 MongoDB 3.0/ upsert:true 只有当您的请求条件匹配字段时,才不会插入不存在的文档 _id.

厘米。:
https://docs.mongodb.org/manua ... rt-id
为什么不使用 user_name 对于用户作为唯一标识符?

由于字段自动增加,因为标识符是环境中使用的不良做法。 mongodb, 特别是如果你想使用分段
=> 所有插入件都将在最后一个片段上发生
= > 簇 mongodb 我们必须经常放松 / 重新分发数据。
/目前它不会发生在系统上,因为您仍在使用生成的字段 _id/

当然,您还可以在用户ID字段上创建一个唯一的索引。 :
https://docs.mongodb.org/manua ... nique

要回复问题请先登录注册