我有像这样的东西
{
  name: 'Object 1',
  fruitList: ['apple','pear','orange','grape']
},
{
  name: 'Object 2',
  fruitList: ['melon','pear','apple','kiwi']
}我需要检索所有在pear之前具有fruitList的对象,在本例中,它只意味着Object 1。我是否可以执行一个自定义匹配函数,对该列表进行迭代并检查它是否与我的条件匹配?
发布于 2022-03-10 20:40:07
您需要一种机制来比较所讨论的水果的索引,并将比较作为与$expr操作符的匹配条件。利用聚合管道操作符:
$indexOfArray -在数组中搜索指定值的出现,并返回第一个事件的数组索引(基于零)。$subtract -返回两个索引之间的差异。如果这个值是负值,那么苹果就会出现在梨前面。$lt -在$expr查询中使用的比较操作符,它比较两个值,并在第一个值小于第二个值时返回true。要大致了解这些操作符在聚合管道中的作用,请查看下面的蒙戈游乐场。
您需要的实际查询如下:
db.collection.find({
    $expr: {
        lt: [
            { 
                $subtract: [
                    { $indexOfArray: [ '$fruitList', 'apple' ] },
                    { $indexOfArray: [ '$fruitList', 'pear' ] }
                ] 
            },
            0
        ]
    }
})对于基于通用正则表达式的解决方案,例如,fruitList数组可能包含一篮子各种水果(在不同情况下):
"fruitList" : [ 
    "mango", 
    "Apples", 
    "Banana", 
    "strawberry", 
    "peach", 
    "Pears"
]以下查询可以解决此问题:
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
        ]
    }
})https://stackoverflow.com/questions/71429219
复制相似问题