Open Elias23 opened 2 months ago
There are some serious changes in the original solution provided by @zhenyabodukhin. Would like to know how these performed since then. Unit tests will make the thing perfect I guess.
@torshid Only wrap arrays if there exists in filter not enough. You should combine them like this: "$anyElementTrue": { "$map": { "input": { "$ifNull": [ "$tasks", [] ] }, "in": { "$anyElementTrue": { "$map": { "input": { "$ifNull": [ "$$this.groupRecipient", [] ] }, "in": { "$and": [ { "$eq": [ "$$this.tenantId", { "$uuid": "4ec6e247-895f-47fa-b427-cecf2ac0f54f" } ] }, { "$eq": [ "$$this.groupName", "PLATFORM_OPERATOR" ] }, { "$anyElementTrue": { "$map": { "input": { "$ifNull": [ "$$this.roles", [] ] }, "in": { "$and": [ { "$isArray": [ [ "ORDER_MANAGER" ] ] }, { "$in": [ "$$this", [ "ORDER_MANAGER" ] ] } ] } } } } ] } } } } } }
I added cache to TransformerUtils, but its not works if you have similar paths in filter (only first will be applied). I can post my solution if it necessary.
@torshid Check last commit. https://github.com/zhenyabodukhin/springfilter/tree/bug/nested-search-mongo
For example “tasks.text: ‘value1’ and tasks.text: ‘value2’” will not work. In this case you can refactor like this “tasks.text in [‘value1’, ‘value2’]” and it will work. But if we have like this “tasks.date:> ‘value1’ and tasks.date:< ‘value2’” will not work and this is a problem. In my project we escape this case, but for you this is bad solution :) When i sad “combine” i mean combine by arrays path.
I guess problem with same paths in filter is appear because i cache nodes and in wrapArrays methods i invokes method transform(), so again invokes wrapArrays and cache not work properly. So i added processedPath to solve this problem, as a result we have issue with same paths. I think if we has opportunity not to use transform() in arrayPaths() this problem will be solved.
In my case I don't have nested Collections, which simplifies the issue for me. I added a post-processing stage to the filter generation, which flattens out nested and and or. Afterward, I merge the paths in the same and/or block if the mapping matches. I added some simple tests.
Not sure how to provide an integration test like proof that it works for simple collections. Here is an example: filter: active=false and groupMemberships.entryDate= '1951-12-03T00:00:00Z' and groupMemberships.leavingDate= '1955-12-04T00:00:00Z' result:
{
"$expr": {
"$and": [
{
"$eq": [
"$active",
false
]
},
{
"$anyElementTrue": {
"$map": {
"input": {
"$ifNull": [
"$groupMemberships",
[]
]
},
"as": "this",
"in": {
"$and": [
{
"$eq": [
"$$this.entryDate",
{
"$date": {
"$numberLong": "-570585600000"
}
}
]
},
{
"$eq": [
"$$this.leavingDate",
{
"$date": {
"$numberLong": "-444268800000"
}
}
]
}
]
}
}
}
}
]
}
}
Based on the described solution in the issue thread resolves turkraft/springfilter#334. Have not yet implemented a fix for the Date problem.