diff --git a/lib/helpers/update/removeUnusedArrayFilters.js b/lib/helpers/update/removeUnusedArrayFilters.js index d4606285212..fbe62c2096c 100644 --- a/lib/helpers/update/removeUnusedArrayFilters.js +++ b/lib/helpers/update/removeUnusedArrayFilters.js @@ -7,12 +7,33 @@ */ module.exports = function removeUnusedArrayFilters(update, arrayFilters) { - const updateKeys = Object.keys(update).map(key => Object.keys(update[key])).reduce((cur, arr) => cur.concat(arr), []); - return arrayFilters.filter(obj => { - const firstKey = Object.keys(obj)[0]; - const firstDot = firstKey.indexOf('.'); - const arrayFilterKey = firstDot === -1 ? firstKey : firstKey.slice(0, firstDot); - - return updateKeys.find(key => key.includes('$[' + arrayFilterKey + ']')) != null; + const updateKeys = Object.keys(update) + .map((key) => Object.keys(update[key])) + .reduce((cur, arr) => cur.concat(arr), []); + return arrayFilters.filter((obj) => { + return _checkSingleFilterKey(obj, updateKeys); }); -}; \ No newline at end of file +}; + +function _checkSingleFilterKey(arrayFilter, updateKeys) { + const firstKey = Object.keys(arrayFilter)[0]; + + if (firstKey === '$and' || firstKey === '$or') { + if (!Array.isArray(arrayFilter[firstKey])) { + return false; + } + return ( + arrayFilter[firstKey].find((filter) => + _checkSingleFilterKey(filter, updateKeys) + ) != null + ); + } + + const firstDot = firstKey.indexOf('.'); + const arrayFilterKey = + firstDot === -1 ? firstKey : firstKey.slice(0, firstDot); + + return ( + updateKeys.find((key) => key.includes('$[' + arrayFilterKey + ']')) != null + ); +} diff --git a/test/helpers/update.removeUnusedArrayFilters.test.js b/test/helpers/update.removeUnusedArrayFilters.test.js new file mode 100644 index 00000000000..d5b82f0a30f --- /dev/null +++ b/test/helpers/update.removeUnusedArrayFilters.test.js @@ -0,0 +1,19 @@ +'use strict'; + +const assert = require('assert'); +const removeUnusedArrayFilters = require('../../lib/helpers/update/removeUnusedArrayFilters'); + +describe('removeUnusedArrayFilters', function() { + it('respects `$or` (gh-10696)', function() { + const update = { + $set: { + 'requests.$[i].status.aa': 'ON_GOING', + 'requests.$[i].status.bb': 'ON_GOING' + } + }; + const arrayFilters = [{ $or: [{ 'i.no': 1 }] }]; + + const ret = removeUnusedArrayFilters(update, arrayFilters); + assert.deepEqual(ret, [{ $or: [{ 'i.no': 1 }] }]); + }); +}); \ No newline at end of file