go-jsonlogic-mongodb
Convert JsonLogic into a MongoDB aggregate query.
How to use
Use the Convert()
function with your jsonLogic as parameter and get your mongo pipeline generated.
func Convert(rules io.Reader) (bson.D, error)
Examples
Equal operator
Json Logic input
{"==": [1, 1]}
Mongo output
bson.D{{
Key: "$eq",
Value: bson.A{
Key: "1",
Value: 1.0
}
}}
Not Equal operator
Json Logic input
{"!=": ["Hello", "Bonjour"]}
Mongo output
bson.D{{
Key: "$ne",
Value: bson.A{"Hello", "Bonjour"}
}}
Not operator
Json Logic input
{"!": "true"}
Mongo output
bson.D{{
Key: "$not",
Value: "true"
}}
Var operator
Json Logic input
{"==": ["kube-system", {"var": ".metadata.namespace"}]}
Mongo output
bson.D{{
Key: "$eq",
Value: bson.A{
"kube-system",
"$metadata.namespace"
}
}}
And & Or operators
And & Or operators work the same way, just specify what operator is needed it will result in a mongo $and
or $or
.
Json Logic input
{
"and": [
{
"==": [
1,
1
]
},
{
"!=": [
"Hello",
"Bonjour"
]
}
]
}
Mongo output
bson.D{{
Key: "$and",
Value: bson.A{
bson.D{{
Key: "$eq",
Value: bson.A{
1.0,
1.0
}
}},
bson.D{{
Key: "$ne",
Value: bson.A{
"Hello",
"Bonjour"
}
}}
}
}}
Custom operator
In order to add a custom operator, you need to use the AddOperator
function.
To make it work, it is mandatory to add your custom operator on the jsonlogic
library side too, otherwise, go-jsonlogic-mongodb
will not validate it.
Example :
Create your custom function
func isKeyValue(value interface{}) (primitive.D, error) {
parsed, _ := value.([]interface{})
key := parsed[1].(string)
val := parsed[2].(string)
firstArgument, internalError := InternalConvert(value.([]interface{})[0])
if internalError != nil {
return nil, internalError
}
return bson.D{{
Key: "$match",
Value: bson.D{{
Key: "$expr", Value: bson.D{{
Key: "$eq", Value: bson.A{
bson.D{{
Key: "$getField", Value: bson.D{
{Key: "field", Value: bson.D{{Key: "$literal", Value: key}}},
{Key: "input", Value: firstArgument},
},
}},
val,
},
}},
}},
}}, nil
}
Add go-jsonlogic-mongodb custom operator
AddOperator("is_key_value", isKeyValue)
Override the jsonlogic
operator, if you are not interested in applying the jsonlogic with your custom operator in the future, you can override it with an empty function like following :
jsonlogic.AddOperator(name, func(values interface{}, data interface{}) (result interface{}) { return })
This way, you can achieve this :
{
"is_key_value": [
{
"var":".metadata.labels"
},
"app.kubernetes.io/name",
"kubees"
]
}
Mongo output
bson.D{{
Key: "$match", Value: bson.D{{
Key: "$expr", Value: bson.D{{
Key: "$eq", Value: bson.A{
bson.D{{
Key: "$getField", Value: bson.D{
{
Key: "field", Value: bson.D{{
Key: "$literal", Value: "app.kubernetes.io/name"
}}
},
{
Key: "input", Value: "$metadata.labels"
}
}}
},
"kubees"
}
}}
}}
}}