javascript - 在 MongoDB 文档中移动元素
问题描述
背景:
客户是具有名称字段的对象。
线是具有以下字段的对象:
inLine
- 一系列客户currentCustomer
- 一个客户processed
- 一系列客户
集合“行”包含作为行对象的文档。
问题:
我正在尝试实现一个可以执行以下操作的程序:
- 推
currentCustomer
到processed
- 设置
currentCustomer
为第一个元素inLine
- 弹出第一个元素
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:管道阶段规范对象必须只包含一个字段。
多阶段聚合方法
db.collection('line').findOneAndUpdate({
_id: new ObjectId(lineId),
}, [{
$set: {
currentCustomer: '$inLine.0',
},
}, {
$pop: {
inLine: -1,
},
}, {
$push: {
processed: '$currentCustomer',
},
}]);
但是,$pop
和$push
是无法识别的管道阶段名称。
我尝试只使用$set
阶段来制作它,但它最终变得非常丑陋,我仍然无法让它工作。
解决方案
根据turivishal 的回答,它是这样解决的:
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 - Expo/React Native Fetch API 不返回文本/纯文本数据
- c++ - 找到一种方法将匹配的键和值从映射推回向量
- ruby-on-rails - Rspec:控制器操作未重新路由
- vba - 保存联系人后创建约会
- kubernetes - VMSS - LoadBalancer 默认情况下未关联的后端池
- mql5 - 关于 MQL5,如何关闭交易并进入交易
- umbraco - 在 Umbraco 8 中访问图像 URL
- javascript - 更简洁的 css/sass 关键帧代码编写方式
- java - 如何在 Hadoop 中对自定义可写类型进行排序
- ubuntu - 无法在 VPN 后面 ping 本地 Ubuntu 服务器,但本地 SSH 工作正常?