【问题标题】:How to aggregate two collections where a field from one collection is greater than the other如何聚合两个集合,其中一个集合中的字段大于另一个集合
【发布时间】:2017-07-12 01:43:43
【问题描述】:

我有两个集合,我们称它们为集合 A 和集合 B,它们都有一个价格字段和项目编号。所以假设每个中有 2 个项目:

集合 A:

名称 = item1 ,价格 = 30

名称 = item2 ,价格 = 20

集合 B:

名称 = item1 ,价格 = 50

名称 = item2 ,价格 = 10

我想显示集合 A 的价格大于集合 B 的价格的项目。对于上面的示例,例如 item2。

如何编写这样的查询?我正在使用 robomongo。

(编辑)

跟进我之前的问题;

我想显示集合 A 的价格大于集合 B 的价格 *(汇率)+(某个常数)的项目

假设条件是;

其中A的价格> B的价格*1.5+4

所以在这种情况下,它仍应显示相同的项目。

假设条件是;

其中A的价格> B的价格*1.5+10

那么它不应该显示任何项目

【问题讨论】:

    标签: python mongodb mongodb-query aggregation-framework robo3t


    【解决方案1】:

    您可以使用 $lookup 运算符首先从 collectionAcollectionB 进行连接,然后使用 $unwind 展平从结果返回的单元素数组 strong> 然后使用 $redact 管道对文档进行文档级别的编辑 匹配指定条件的使用$$KEEP系统变量保留,不满足条件的使用$$PRUNE丢弃。最后,您需要运行以下聚合管道:

    var exchangeRate = 1.5;
    db.collectionA.aggregate([
        { "$match": { "price": { "$exists": true }, "name": { "$exists": true } } },
        {
            "$lookup": {
                "from": "collectionB",
                "localField": "name",
                "foreignField": "name",
                "as": "collectionB"
            }
        },
        { "$unwind": "$collectionB" },
        {
            "$redact": {
                "$cond": [
                    { 
                        "$gt": [
                            "$price", {
                                "$add": [
                                    { "$multiply": [ "$collectionB.price", exchangeRate ] },
                                    4
                                ]
                            }
                        ]
                    },
                    "$$KEEP",
                    "$$PRUNE"
                ]
            }
        }
    ])
    

    Robomongo 演示

    填充测试集合:

    db.collectionA.insert([
        { "name": "item1", "price": 30 },
        { "name": "item2", "price": 20 }    
    ])
    
    db.collectionB.insert([
        { "name": "item1", "price": 50 },
        { "name": "item2", "price": 10 }    
    ])
    

    运行和调试聚合管道:

    样本输出:

    {
        "_id" : ObjectId("58ad50a429b2961777f91c95"),
        "name" : "item2",
        "price" : 20,
        "collectionB" : {
            "_id" : ObjectId("58ad50a429b2961777f91c97"),
            "name" : "item2",
            "price" : 10
        }
    }
    

    【讨论】:

    • 非常感谢您非常详细和精彩的回答!只是为了跟进这一点;如果第二个集合的价格是其他货币,我想比较集合 B 中的 item1 价格(在集合 A 中)与 item1 价格*(汇率)(比如说 1.5)。我该如何结合这个逻辑?或者,如果我想添加缓冲区,假设我想获取 A 中的 item1 价格大于 B 中的 item1(价格 + 10 )的项目。我尝试将 + 这个添加到您的代码中,但没有奏效
    • 由于汇率变化,我不想用 1.5 更新集合 B 的价格。假设明天价格将是 1.6,我想查看 A 中价格大于(price*(exchange rate) + (some number)) 在 B 中的项目名称匹配。我用这个跟进编辑了这个问题。因此,您可以再次查看问题以获得更好的标记和更好的解释。 (我不知道如何在 cmets 中进行标记 - 我对论坛很陌生 =))。感谢您的帮助!
    • 请注意,变色龙问题在这里被认为是不合适的,请参阅thread 了解更多详细信息。但是,我将尽我所能回答您的后续问题。您可以将arithmetic operators 合并到您的$redact 条件表达式中,如上面的编辑。
    猜你喜欢
    • 2017-03-14
    • 1970-01-01
    • 1970-01-01
    • 2013-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    相关资源
    最近更新 更多