gpt4 book ai didi

node.js - mongoDB/Node.js 上的重复索引

转载 作者:太空宇宙 更新时间:2023-11-04 00:03:24 26 4
gpt4 key购买 nike

我这边有一个奇怪的问题/行为:我有一个 mongoDB 集合,在 _id 字段上有一个唯一索引。

为了向集合中添加元素并确保我不会删除已存在的文档,我使用以下请求:

db.getCollection('name').updateOne({
"_id": "5bf9c75b478b493e9c989d96"
}, {
"$setOnInsert": {
"_id": "5bf9c75b478b493e9c989d96",
"offset": 53,
"data": {
// some data
}
}
}, {
'upsert' : true
})

如果我没记错的话,这意味着:尝试找到 :id,如果不存在,则插入漂亮的结构。如果找到 :id,则不会触发 $setOnInsert 并忽略该请求。

这在 robomongo 中工作得很好,但是当我尝试将它集成到我的 node.js 程序中时,如果找到具有现有 :id 的结构,它会抛出重复的 Id 异常,因为它似乎仍在尝试写入它。

我们是否同意整个操作(查找、设置、修改或不修改集合)应该是原子的?我知道问题出在我在微服务环境中执行此操作的事实,因此有很多线程试图在 Mongo 上执行相同的操作,这就是为什么我需要它是原子的。

根据亚历克斯的回答进行编辑:

mongo 错误:

{
"driver": true,
"name": "MongoError",
"index": 0,
"code": 11000,
"errmsg": "E11000 duplicate key error collection: eventSourcing.name index: _id_ dup key: { : ObjectId('5bfbd5a0478b493e9c989db0') }"
}

我的代码:

public saveIfAbsent(aggregate: T, writer: Writer<T, Schema>): Promise<UpdateWriteOpResult> {
const element = writer(aggregate)

if (element['_id'] !== aggregate._id) {
throw new Error("should not happen")
}

return super.collection().then((collection) => {
return collection.updateOne({
'_id': aggregate._id
}, {
'$setOnInsert': element
}, {
'upsert' : true
})
}).catch((e) => {
console.log(e)
return Promise.reject(e)
})
}

关于如何让它发挥作用有什么想法吗?我想要的东西只有在结构不存在时才能够写入,否则不执行任何操作。

谢谢

编辑:

看来我正在尝试做一些不可能的事情......或者我做错了。

const db = new Database()

const data = new Array<string>()
const length = 500; // user defined length

for (var i = 0; i < length; i++) {
data.push('toto')
}

Promise.all(data.map((e) => db.db.then((db) => db.collection('name').updateOne({
'_id': 1,
}, {
'$setOnInsert': {
'id': 1,
'data': e
}
}, {
upsert: true
})))).then(() =>
console.log('true'))

这段代码尝试插入基类 { 'id': 'data': 'toto' }。

预期行为:

  • 第一个循环,它什么也没找到,然后插入一个 { 'id': 'data': 'toto' } 因为标志 '$setOnInsert' 处于事件状态

  • 所有其他的, { '_id': 1 } 应该返回一些东西,所以 '$setOnInsert' 永远不应该被写入,所以它应该“通过”什么也不做

当前行为:

  • 第一个循环,它什么也没找到,然后插入一个 { 'id': 'data': 'toto' } 因为标志 '$setOnInsert' 处于事件状态

  • UnhandledPromiseRejectionWarning: MongoError: E11000 重复键错误集合: eventSourcing.name index: _id_ dup key: { : 1 } 崩溃。不知何故,它似​​乎试图在“$setOnInsert”部分中写入一些内容=>这似乎只有在集合名称从数据库中删除时才会发生。如果集合已经存在,它似乎不会崩溃(令人惊讶)

适用于 Node JS v3.1.10 的 native mongo DB 驱动程序

我试图在我的代码中实现预期的行为,有什么方法可以做到吗?

最佳答案

this.representationId(aggregate) 不会返回与 element._id 相同的数据/类型。

要么先检查一下:

if (this.representationId(aggregate) !== element._id) {
throw new Error("Impossible happened!")
}

或在查询中使用element._id

return collection.updateOne({
'_id': element._id
}, {
'$setOnInsert': element
}, {
'upsert': true
})
})

或者两者都做。

关于node.js - mongoDB/Node.js 上的重复索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53517015/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com