javascript - 在 MongoDB 文档中移动元素

标签 javascript mongodb mongodb-nodejs-driver

背景:

客户是一个具有名称字段的对象。

线是一个具有以下字段的对象:

  • inLine - 客户数组
  • currentCustomer - 客户
  • 已处理 - 一组客户

集合“line”包含作为行对象的文档。


问题:

我正在尝试实现一个执行以下操作的程序:

  1. currentCustomer推送到已处理
  2. currentCustomer 设置为 inLine 中的第一个元素
  3. 弹出inLine的第一个元素

由于一个字段的新值取决于另一个字段的先前值,因此原子性在这里很重要。

到目前为止我尝试过的:

天真的方法

db.collection('line').findOneAndUpdate({
    _id: new ObjectId(lineId),
}, {
    $set: {
        currentCustomer: '$inLine.0',
    },
    $pop: {
        inLine: -1,
    },
    $push: {
        processed: '$currentCustomer',
    },
});

但是,currentCustomer 设置为字面意思为“$inLine.0”的字符串,而 processed 则设置为字面意思为“$currentCustomer”的字符串。

聚合方法

db.collection('line').findOneAndUpdate({
    _id: new ObjectId(lineId),
}, [{
    $set: {
        currentCustomer: '$inLine.0',
    },
    $pop: {
        inLine: -1,
    },
    $push: {
        processed: '$currentCustomer',
    },
}]);

但是,我收到以下错误:

MongoError: A pipeline stage specification object must contain exactly one field.

多阶段聚合方法

db.collection('line').findOneAndUpdate({
    _id: new ObjectId(lineId),
}, [{
    $set: {
        currentCustomer: '$inLine.0',
    },
}, {
    $pop: {
        inLine: -1,
    },
}, {
    $push: {
        processed: '$currentCustomer',
    },
}]);

但是,$pop$push 是无法识别的管道阶段名称。

我尝试仅使用 $set 阶段来制作它,但结果非常丑陋,而且我仍然无法让它工作。

最佳答案

基于turivishal's answer ,它是这样解决的:

db.collection('line').findOneAndUpdate({
    _id: new ObjectId(lineId),
}, [{
    $set: {
        // currentCustomer = inLine.length === 0 ? null : inLine[0]
        currentCustomer: {
            $cond: [
                { $eq: [{ $size: '$inLine' }, 0] },
                null,
                { $first: '$inLine' },
            ],
        },
        // inLine = inLine.slice(1)
        inLine: {
            $cond: [
                { $eq: [{ $size: '$inLine' }, 0] },
                [],
                { $slice: ['$inLine', 1, { $size: '$inLine' }] },
            ],
        },
        // if currentCustomer !== null then processed.push(currentCustomer)
        processed: {
            $cond: [
                {
                    $eq: ['$currentCustomer', null],
                },
                '$processed',
                {
                    $concatArrays: [
                        '$processed', ['$currentCustomer'],
                    ],
                }
            ],
        },
    },
}]);

关于javascript - 在 MongoDB 文档中移动元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64861667/

相关文章:

javascript - 使用 Angular 和 Express 将数据保存在 mongodb 中

javascript - 单击按钮后显示图像

mongodb - Mongoose :如何将模式字段设置为 ID?

mongodb - 根据聚合管道 MongoDB Atlas 触发器中的条件更新多个字段

sveltekit - 如何在 SvelteKit 项目中使用 mongodb?

javascript - 添加元素的进度条

javascript - 用点替换数字

javascript - 为什么从 onclick 属性调用的函数 write() 解析为 document.write()?

javascript - AJAX jquery 表单发布不工作