mongodb 中如何将十六进制字符串转换为数字?
How do you convert a hexadecimal string into a number in mongodb?
我有一个包含如下字符串的集合:
left_eye_val : "0x0", right_eye_val : "0x2"
我正在设置一些派生字段作为聚合管道的一部分,该管道在第一阶段必须将十六进制字符串“0x0”、“0x2”转换为数字。
我试过的运算符:
{$toInt:"$left_eye_val"}
returns Illegal hexadecimal input in $convert with onError value:0x0
有没有办法使用内置的 mongodb 运算符将这些字符串转换为数字?如果没有,可以通过哪些方式实现这一目标?
暂无此功能,见Support base conversion in $convert
您可以这样定义函数:
function decimalToBase(input, base) {
// works up to 72057594037927928 / FFFFFFFFFFFFF8
var field = "$" + input;
return {
$let: {
vars: {
bits: {
$reduce: {
input: { $range: [0, 56] },
initialValue: [{ dec: field }],
in: {
$cond: {
if: { $gt: [{ $last: "$$value.dec" }, 0] },
then: {
$concatArrays: ["$$value",
[{
b: { $substrBytes: ["0123456789ABCDEF", { $mod: [{ $last: "$$value.dec" }, base] }, 1] },
dec: { $trunc: { $divide: [{ $last: "$$value.dec" }, base] } }
}]
]
},
else: "$$value"
}
}
}
}
},
in: {
$reduce: {
input: { $reverseArray: "$$bits.b" },
initialValue: "",
in: { $concat: ["$$value", "$$this"] }
}
}
}
}
};
function baseToDecimal(input, base) {
// works up to 72057594037927928 / FFFFFFFFFFFFF8
var field = "$" + input;
return {
$sum: {
$map: {
input: { $range: [0, { $strLenBytes: field }] },
in: {
$multiply: [
{ $pow: [base, { $subtract: [{ $strLenBytes: field }, { $add: ["$$this", 1] }] }] },
{ $indexOfBytes: ["0123456789ABCDEF", { $toUpper: { $substrBytes: [field, "$$this", 1] } }] }
]
}
}
}
};
}
然后使用它,例如这样:
db.collection.insertOne({ hex: "A3F" })
db.collection.aggregate({ $set: { decimal: baseToDecimal("hex", 16)} })
如果十六进制字符串前面不包含“0x”,@Domscheit 的答案有效;如果是,则修改@Domscheit 发布的函数,如下所示:
function baseToDecimal(input, base) {
// works up to 72057594037927928 / FFFFFFFFFFFFF8
var field = input;
return {
$sum: {
$map: {
input: { $range: [0, { $strLenBytes: field }] },
in: {
$multiply: [
{ $pow: [base, { $subtract: [{ $strLenBytes: field }, { $add: ["$$this", 1] }] }] },
{ $indexOfBytes: ["0123456789ABCDEF", { $toUpper: { $substrBytes: [field, "$$this", 1] } }] }
]
}
}
}
};
}
并调用如下,使用replaceOne
函数去掉x
db.collection.aggregate([{$set:{lHex: {$replaceOne: {input:"$hex", find:"x", replacement: "0"}}}}, {$set: {decimal: baseToDecimal("$lHex", 16)}}])
我有一个包含如下字符串的集合:
left_eye_val : "0x0", right_eye_val : "0x2"
我正在设置一些派生字段作为聚合管道的一部分,该管道在第一阶段必须将十六进制字符串“0x0”、“0x2”转换为数字。
我试过的运算符:
{$toInt:"$left_eye_val"}
returns Illegal hexadecimal input in $convert with onError value:0x0
有没有办法使用内置的 mongodb 运算符将这些字符串转换为数字?如果没有,可以通过哪些方式实现这一目标?
暂无此功能,见Support base conversion in $convert
您可以这样定义函数:
function decimalToBase(input, base) {
// works up to 72057594037927928 / FFFFFFFFFFFFF8
var field = "$" + input;
return {
$let: {
vars: {
bits: {
$reduce: {
input: { $range: [0, 56] },
initialValue: [{ dec: field }],
in: {
$cond: {
if: { $gt: [{ $last: "$$value.dec" }, 0] },
then: {
$concatArrays: ["$$value",
[{
b: { $substrBytes: ["0123456789ABCDEF", { $mod: [{ $last: "$$value.dec" }, base] }, 1] },
dec: { $trunc: { $divide: [{ $last: "$$value.dec" }, base] } }
}]
]
},
else: "$$value"
}
}
}
}
},
in: {
$reduce: {
input: { $reverseArray: "$$bits.b" },
initialValue: "",
in: { $concat: ["$$value", "$$this"] }
}
}
}
}
};
function baseToDecimal(input, base) {
// works up to 72057594037927928 / FFFFFFFFFFFFF8
var field = "$" + input;
return {
$sum: {
$map: {
input: { $range: [0, { $strLenBytes: field }] },
in: {
$multiply: [
{ $pow: [base, { $subtract: [{ $strLenBytes: field }, { $add: ["$$this", 1] }] }] },
{ $indexOfBytes: ["0123456789ABCDEF", { $toUpper: { $substrBytes: [field, "$$this", 1] } }] }
]
}
}
}
};
}
然后使用它,例如这样:
db.collection.insertOne({ hex: "A3F" })
db.collection.aggregate({ $set: { decimal: baseToDecimal("hex", 16)} })
如果十六进制字符串前面不包含“0x”,@Domscheit 的答案有效;如果是,则修改@Domscheit 发布的函数,如下所示:
function baseToDecimal(input, base) {
// works up to 72057594037927928 / FFFFFFFFFFFFF8
var field = input;
return {
$sum: {
$map: {
input: { $range: [0, { $strLenBytes: field }] },
in: {
$multiply: [
{ $pow: [base, { $subtract: [{ $strLenBytes: field }, { $add: ["$$this", 1] }] }] },
{ $indexOfBytes: ["0123456789ABCDEF", { $toUpper: { $substrBytes: [field, "$$this", 1] } }] }
]
}
}
}
};
}
并调用如下,使用replaceOne
函数去掉x
db.collection.aggregate([{$set:{lHex: {$replaceOne: {input:"$hex", find:"x", replacement: "0"}}}}, {$set: {decimal: baseToDecimal("$lHex", 16)}}])