我正在尝试想出一种方法来解析
string
类型的三个不同字段中的“数字”,将它们转换为真正的数字类型,并将它们添加到一个新字段中。我必须在聚合管道中执行此操作,以便当我的文档进入我要放置的“组”阶段时,我可以创建所有文档的 item1、item2 和 item3 字段的总和。
该集合包含以下对象:
{
"groupId": 1,
"item1": "$300.00 - Jason"
"item2": "$25.50 - Stephanie"
"item3": ""
}
每个文档中总会包含三个项目,但并非每个项目都会包含某些内容。
在聚合管道中进行操作后,我希望得到这样的文档:
{
"groupId": 1,
"itemTotal": 325.5
}
管道的下一阶段将是按 groupId 对文档进行分组,获取该组的 itemTotal(我可以处理这个问题,因为那时它会很简单)。
我尝试的第一件事是 $regexFind 但看起来我一次只能在一个字段上运行它,我希望我可以解析所有三个数字并一步添加它们。据我所知,前进的唯一途径是做类似的事情:
db.collection.aggregate([
{
$project: {
item1NumberString: { $regexFind: {input: "item1", regex: /\$(\d{1,}\.\d\d)/} },
item2NumberString: { $regexFind: {input: "item2", regex: /\$(\d{1,}\.\d\d)/} },
item3NumberString: { $regexFind: {input: "item3", regex: /\$(\d{1,}\.\d\d)/} }
}
},
{
$addFields: {
"itemTotal": {$add: [
{$toInt: "$item1NumberString.captures.0"},
{$toInt: "$item2NumberString.captures.0"},
{$toInt: "item3NumberString.captures.0"}
] }
}
}
]);
但如果没有必要,将其分解为多个管道阶段似乎效率低下。有没有更简单的方法来实现这一点?也许通过创造性地使用连接运算符或其他东西?
我还需要将此答案转换为 Spring MongoDB 查询
对 3 个字段重复以下步骤:
-
并获得第一个令牌/部分$convert
将字符串更改为双倍然后对 3 个解析后的双精度数求和。
db.collection.aggregate([
{
$set: {
// split by - and get first token
item1Parsed: {
$first: {
"$split": [
"$item1",
" - "
]
}
},
item2Parsed: {
$first: {
"$split": [
"$item2",
" - "
]
}
},
item3Parsed: {
$first: {
"$split": [
"$item3",
" - "
]
}
}
}
},
{
"$set": {
// remove dollar sign
"item1Parsed": {
"$replaceAll": {
"input": "$item1Parsed",
"find": {
$literal: "$"
},
"replacement": ""
}
},
"item2Parsed": {
"$replaceAll": {
"input": "$item2Parsed",
"find": {
$literal: "$"
},
"replacement": ""
}
},
"item3Parsed": {
"$replaceAll": {
"input": "$item3Parsed",
"find": {
$literal: "$"
},
"replacement": ""
}
}
}
},
{
$set: {
// parse to double
item1Parsed: {
"$convert": {
"input": "$item1Parsed",
"to": "double",
"onError": 0.0
}
},
item2Parsed: {
"$convert": {
"input": "$item2Parsed",
"to": "double",
"onError": 0.0
}
},
item3Parsed: {
"$convert": {
"input": "$item3Parsed",
"to": "double",
"onError": 0.0
}
}
}
},
{
$project: {
// sum them up
groupId: 1,
itemTotal: {
$sum: [
"$item1Parsed",
"$item2Parsed",
"$item3Parsed"
]
}
}
}
])