如果在数组中找不到匹配项,则返回第一个元素 [英] Return first element if no match found in array

查看:89
本文介绍了如果在数组中找不到匹配项,则返回第一个元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下文件:

{
    _id: 123,
    state: "AZ",
    products: [
        {
            product_id: 1,
            desc: "P1"
        },
        {
            product_id: 2,
            desc: "P2"
        }   
    ]
}

我需要编写一个查询,以从状态为"AZ"且product_id为2的products数组中返回单个元素.如果找不到匹配的product_id,则从products数组中返回第一个(或任何一个)元素

I need to write a query to return a single element from the products array where state is "AZ" and product_id is 2. If the matching product_id is not found, then return the first (or any) element from the products array.

例如:如果product_id为2(找到匹配项),则结果应为:

For example: If product_id is 2 (match found), then the result should be:

products: [
    {
        product_id: 2,
        desc: "P2"
    }   
]

如果product_id为3(未找到),则结果应为:

If the product_id is 3 (not found), then the result should be:

products: [
    {
        product_id: 1,
        desc: "P1"
    }   
]

找到匹配项后,我能够满足一个条件,但不确定如何在同一查询中满足第二个条件:

I was able to meet one condition when the match is found but not sure how to satisfy the second condition in the same query:

db.getCollection('test').find({"state": "AZ"}, {_id: 0, state: 0, products: { "$elemMatch": {"product_id": "2"}}})

我也尝试使用聚合管道,但是找不到可行的解决方案.

I tried using the aggregation pipeline as well but could not find a working solution.

注意:这与以下问题不同,因为如果找不到匹配项,我需要返回一个默认元素: 仅检索对象中的查询元素MongoDB集合中的数组

Note: This is different from the following question as I need to return a default element if the match is not found: Retrieve only the queried element in an object array in MongoDB collection

推荐答案

如果您不在乎要返回哪个元素,那么这就是要走的路(如果没有则将获得数组中的最后一个元素匹配,因为 $ indexOfArray 将返回-1):

If you don't care which element you get back then this is the way to go (you'll get the last element in the array in case of no match since $indexOfArray will return -1):

db.getCollection('test').aggregate([{
    $addFields: {
        "products": {
            $arrayElemAt: [ "$products", { $indexOfArray: [ "$products.product_id", 2 ] } ]
        },
    }
}])

如果您要第一个,请改用( $ max 将负责将-1转换为第一个元素的索引0):

If you want the first then do this instead ($max will take care of transforming -1 into index 0 which is the first element):

db.getCollection('test').aggregate([{
    $addFields: {
        "products": {
            $arrayElemAt: [ "$products", { $max: [ 0, { $indexOfArray: [ "$products.product_id", 2 ] } ] } ]
        },
    }
}])

以下是也应在v3.2上运行的版本:

Here is a version that should work on v3.2 as well:

db.getCollection('test').aggregate([{
    "$project": {
        "products": {
            $slice: [{
                $concatArrays: [{
                    $filter: {
                        "input": "$products",
                        "cond": { "$eq": ["$$this.product_id", 2] }
                    }},
                    "$products" // simply append the "products" array
                   // alternatively, you could append only the first or a specific item like this [ { $arrayElemAt: [ "$products", 0 ] } ]
                ]
            },
            1 ] // take first element only
        }
    }
}])

这篇关于如果在数组中找不到匹配项,则返回第一个元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆