Tengo objetos que se ven así.
{ name: 'Object 1', fruitList: ['apple','pear','orange','grape'] }, { name: 'Object 2', fruitList: ['melon','pear','apple','kiwi'] } Necesito recuperar todos los objetos que tienen apple antes que pear en su lista de fruitList , en este ejemplo significaría solo el Object 1 . ¿Puedo hacer una función de coincidencia personalizada que repita esa lista y verifique que coincida con mis criterios?
Necesita un mecanismo para comparar los índices de las frutas en cuestión y usar la comparación como una condición de coincidencia con el operador $expr . Aproveche los operadores de canalización de agregación:
$indexOfArray : busca en una matriz una aparición de un valor especificado y devuelve el índice de matriz (basado en cero) de la primera aparición.$subtract : devuelve la diferencia entre los dos índices. Si el valor es negativo, la manzana aparece antes que la pera en la lista.$lt : el operador de comparación para usar en la consulta $expr que compara dos valores y devuelve verdadero cuando el primer valor es menor que el segundo valor.Para tener una idea aproximada de estos operadores en juego en una canalización de agregación, consulte el siguiente Mongo Playground .
La consulta real que necesita es la siguiente:
db.collection.find({ $expr: { lt: [ { $subtract: [ { $indexOfArray: [ '$fruitList', 'apple' ] }, { $indexOfArray: [ '$fruitList', 'pear' ] } ] }, 0 ] } }) Para una solución genérica basada en expresiones regulares donde la matriz fruitList puede contener una canasta de frutas variadas (en diferentes casos), por ejemplo:
"fruitList" : [ "mango", "Apples", "Banana", "strawberry", "peach", "Pears" ]La siguiente consulta puede abordar este desafío:
const getMapExpression = (fruit) => { return { $map: { input: '$fruitList', as: 'fruit', in: { $cond: [ { $regexMatch: { input: '$$fruit', regex: fruit, options: 'i' } }, { $literal: fruit }, '$$fruit' ] } } } } db.collection.find({ $expr: { $lt: [ { $subtract: [ { $indexOfArray: [ getMapExpression('apple'), 'apple' ] }, { $indexOfArray: [ getMapExpression('pear'), 'pear' ] } ] }, 0 ] } })