Skip to content

Instantly share code, notes, and snippets.

@itslukej
Last active March 16, 2023 19:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save itslukej/6d4e5af915c35002b4ff0f43b44467fa to your computer and use it in GitHub Desktop.
Save itslukej/6d4e5af915c35002b4ff0f43b44467fa to your computer and use it in GitHub Desktop.
JSON Serialiser written in pure mongodb aggregate.
db.aggregate([{
$replaceRoot: {
newRoot: {
_id: '$_id',
data: {
$objectToArray: '$$ROOT'
}
}
}
},
{
$unwind: '$data'
},
{
$project: {
jsonKey: {
$concat: [
'"',
{
$replaceOne: {
input: '$data.k',
find: '"',
replacement: '\\"'
}
},
'"'
]
},
jsonValue: jsonValue()
}
},
{
$group: {
_id: '$_id',
json: {
$push: {
$concat: ['$jsonKey', ':', '$jsonValue']
}
}
}
},
{
$project: {
json: {
$concat: ['{', {
$reduce: {
input: '$json',
initialValue: '',
in: {
$concat: [
"$$value",
{
$cond: [{
$eq: ["$$value", ""]
}, "", ", "]
},
{
$toString: "$$this"
},
],
}
}
}, '}']
}
}
},
{
$group: {
_id: null,
json: {
$push: '$json'
}
}
},
{
$project: {
json: {
$concat: [
'[',
{
$reduce: {
input: '$json',
initialValue: '',
in: {
$concat: [
"$$value",
{
$cond: [{
$eq: ["$$value", ""]
}, "", ", "]
},
{
$toString: "$$this"
},
],
}
}
},
']'
]
}
}
},
])
function jsonValue(f = "$data.v", i = 0) {
if (i > 2) return 'null';
return {
$switch: {
branches: [
// Number
{
case: {
$isNumber: f
},
then: {
$toString: f
}
},
// String
{
case: {
// Check it's a string type
$eq: [{
$type: f
},
'string'
]
},
then: {
// Make sure to escape double quotes
$concat: [
'"',
{
$replaceOne: {
input: f,
find: '"',
replacement: '\\"'
}
},
'"'
]
}
},
// Boolean
{
case: {
$eq: [f, true]
},
then: 'true'
},
{
case: {
$eq: [f, false]
},
then: 'false'
},
// Null
{
case: {
$eq: [f, null]
},
then: 'null'
},
// Array
{
case: {
$isArray: f
},
then: {
// map array
$concat: [
'[',
{
$reduce: {
input: f,
initialValue: '',
in: {
$concat: [
"$$value",
{
$cond: [{
$eq: ["$$value", ""]
}, "", ","]
},
jsonValue("$$this", i + 1)
]
}
}
},
']'
]
}
},
// Object
{
case: {
$eq: [{
$type: f
},
'object'
]
},
then: {
// map object
$concat: [
'{',
{
$reduce: {
input: {
$objectToArray: f
},
initialValue: '',
in: {
$concat: [
"$$value",
{
$cond: [{
$eq: ["$$value", ""]
}, "", ","]
},
{
$concat: [
'"',
{
$replaceOne: {
input: "$$this.k",
find: '"',
replacement: '\\"'
}
},
'":',
jsonValue("$$this.v", i + 1)
]
}
]
}
}
}
]
}
}
],
default: 'null'
}
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment