我试图以各种可能的方式执行此操作,搜索所有资源但无法找到解决看似微不足道的问题的方法。
我有一个从其他地方导入的大量集合,文档field
是字符串而不是数字类型。试图对field
进行排序有效,但自然会进行字符串排序而不是数字排序。执行$sum
或$avg
分别产生0
和null
。
我迫切需要的是一种将$cast
我的字符串字段转换为数值的方法,但这种功能似乎不存在。我已经尝试过像$add: ['field', 0]
或$multiply: ['field', 1]
这样的技巧而没有任何成功,因为算术运算符显然需要数值。似乎没有自动转换。我在$group
和$project
阶段尝试了这一点无济于事。
如果其他一切都失败了,我将不得不通过插入与我的field
对应的新数字字段来更新我的收藏集,但这不是首选解决方案,因为收藏品将经常从一个频繁地重新导入外部来源。
答案 0 :(得分:2)
这里快速刺了一下。希望它是所有正整数(即没有" - "或"。")否则逻辑会变得更复杂。这个想法是把字符串分成字符和"手动"转换为int。给出这样的输入文档:
{ snum: "34567" }
它将创建一个新的var qq
,它是一个实际的int,例如
{ qq: 34567 }
db.foo.aggregate([
{$addFields: {x: {$map: {
input: {$range: [0,{$strLenBytes: "$snum"}] } ,
as: "z",
in: {
$let: {
vars: {c: {$substrBytes:["$snum","$$z",1]}},
in: {
"v" : {$switch:
{
branches: [
{ case: {$eq: [ "0", "$$c" ]}, then: 0}
,{ case: {$eq: [ "1", "$$c" ]}, then: 1}
,{ case: {$eq: [ "2", "$$c" ]}, then: 2}
,{ case: {$eq: [ "3", "$$c" ]}, then: 3}
,{ case: {$eq: [ "4", "$$c" ]}, then: 4}
,{ case: {$eq: [ "5", "$$c" ]}, then: 5}
,{ case: {$eq: [ "6", "$$c" ]}, then: 6}
,{ case: {$eq: [ "7", "$$c" ]}, then: 7}
,{ case: {$eq: [ "8", "$$c" ]}, then: 8}
,{ case: {$eq: [ "9", "$$c" ]}, then: 9}
],
default: "$$c"
}
},
exp: {$subtract: [ {$strLenBytes: "$snum"}, {$add:[1,"$$z"]} ]}
}
}
}
}}
}}
,{$addFields: {qq: {$reduce: {
input: "$x",
initialValue: 0,
in: {$add: [ "$$value", {$multiply: ["$$this.v", {$pow: [ 10, "$$this.exp"]} ]} ]}
}}
}}
]);