是否可以在 mongodb 上聚合多个条件

Posted

技术标签:

【中文标题】是否可以在 mongodb 上聚合多个条件【英文标题】:Is it possible to aggregate with multiple conditions on mongodb 【发布时间】:2020-02-15 07:23:11 【问题描述】:

我有一个定价集合,我想根据卖家查询随时间变化的最大价格变化,但我不知道如何在单个查询中完成此操作。

集合包括

_id
partNumber
seller
price
createdAt

每天应该为每种产品插入大约 30 个价格,但在不是 100% 的现实世界中......

所以我在想这个。

    获取 partNumber 和卖方的 date 获取零件编号和卖家的最新价格 价格差异 按差异排序

mongodb 聚合或其他方法可以实现吗?

【问题讨论】:

您能否根据您的要求添加样本收集数据和响应。 【参考方案1】:

假设我们有 2 个卖家 A 和 B。我们获取了一组数据如下(假设零件编号相同,或者您也可以更改它):

/* 1 createdAt:18/10/2019, 16:48:35*/

    "_id" : ObjectId("5da99f8bd4ce6a7d8bebb442"),
    "partNumber" : 1,
    "seller" : "B",
    "price" : 15,
    "createdAt" : ISODate("2019-10-11T16:13:31.451+05:30")
,

/* 2 createdAt:18/10/2019, 16:48:35*/

    "_id" : ObjectId("5da99f8bd4ce6a7d8bebb441"),
    "partNumber" : 1,
    "seller" : "A",
    "price" : 1,
    "createdAt" : ISODate("2019-10-11T16:13:31.451+05:30")
,

/* 3 createdAt:18/10/2019, 16:48:35*/

    "_id" : ObjectId("5da99f8bd4ce6a7d8bebb440"),
    "partNumber" : 1,
    "seller" : "B",
    "price" : 10,
    "createdAt" : ISODate("2019-10-10T16:13:31.451+05:30")
,

/* 4 createdAt:18/10/2019, 16:48:35*/

    "_id" : ObjectId("5da99f8bd4ce6a7d8bebb43f"),
    "partNumber" : 1,
    "seller" : "A",
    "price" : 10,
    "createdAt" : ISODate("2019-10-10T16:13:31.451+05:30")
,

/* 5 createdAt:18/10/2019, 16:48:35*/

    "_id" : ObjectId("5da99f8bd4ce6a7d8bebb43e"),
    "partNumber" : 1,
    "seller" : "B",
    "price" : 7,
    "createdAt" : ISODate("2019-10-09T16:13:31.451+05:30")
,

/* 6 createdAt:18/10/2019, 16:48:35*/

    "_id" : ObjectId("5da99f8bd4ce6a7d8bebb43d"),
    "partNumber" : 1,
    "seller" : "A",
    "price" : 5,
    "createdAt" : ISODate("2019-10-09T16:13:31.451+05:30")

我们的查询如下:

db.collection.aggregate([
    
        $group: 
            _id:  seller: "$seller", partNumber: "$partNumber" ,
            lastSalesPrice:  $last: "$price" ,
            firstSalesPrice:  $first: "$price" ,
        
    ,
    
        $project: 
            seller: "$_id.seller",
            partNumber: "$_id.partNumber",
            lastSalesPrice: "$lastSalesPrice",
            firstSalesPrice: "$firstSalesPrice",
            diff:  $subtract: ["$lastSalesPrice", "$firstSalesPrice" ] 
        
    ,
    
        $sort:  "diff": -1 
    
]) 

以上查询结果如下:

/* 1 */

    "_id" : 
        "seller" : "B",
        "partNumber" : 1
    ,
    "seller" : "B",
    "partNumber" : 1,
    "lastSalesPrice" : 15,
    "firstSalesPrice" : 7,
    "diff" : 8
,

/* 2 */

    "_id" : 
        "seller" : "A",
        "partNumber" : 1
    ,
    "seller" : "A",
    "partNumber" : 1,
    "lastSalesPrice" : 1,
    "firstSalesPrice" : 5,
    "diff" : -4

【讨论】:

这看起来不错,但还有一个问题。如果卖家 B 没有 2019-10-09 的条目来告诉查询然后使用下一个较旧的查询会发生什么。 在这种情况下,它将自动选择从 2019-10-10 开始的第一个销售价格。我试过了,它工作正常,你也可以试试。 这是真的,但我需要将数据限制为(现在 - 30 天),然后在这种情况下没有旧条目。 此时考虑一下性能。不要根据实际需要向管道添加更多内容。我确保每天都有记录存在,然后您的解决方案完美运行。非常感谢!

以上是关于是否可以在 mongodb 上聚合多个条件的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB聚合操作总结

MongoDB聚合操作总结

在单个聚合查询 mongodb 中组合多个 $samples

mongoTemplate聚合操作Demo

04 MongoDB各种查询操作 以及聚合操作总结

详细教程一文参透MongoDB聚合查询