【问题标题】:Mongo Query to fetch documents on the basis of same field value and those which are not expiredMongo Query 根据相同的字段值和未过期的值获取文档
【发布时间】:2021-09-12 12:00:35
【问题描述】:

我有一些收藏分享,分享收藏中有sharedWith,expiryTime字段。

sharedWith 字段是一个数组,指定已与这些用户进行共享,它包含用户的 ID。

sharedWith : [NumberLong(11),NumberLong(22),NumberLong(33)]

我需要获取已与同一用户完成多次共享的文档,这意味着输出应返回多个具有相同 sharedWith 值的共享文档以及未过期的文档:

// condition to check whether document has been expired or not

currentTime < expiryTime // means the sharing document has not been expired

currentTime :(今天的现在时间)

expiryTime : (expiryTime 是共享集合中的一个字段)

例子:

A 
{sharedWith : [NumberLong(123),NumberLong(456)],
 expiryTime : ISODate("2021-07-03T06:22:29.021Z")
},
B 
{sharedWith : [NumberLong(456)],
 expiryTime : ISODate("2021-07-03T06:22:29.021Z")
},
C 
{sharedWith : [NumberLong(123456)],
 expiryTime : ISODate("2021-07-03T06:22:29.021Z")
},
D
{sharedWith : [NumberLong(111111)],
 expiryTime : ISODate("2021-06-03T06:22:29.021Z")
},

这种情况的输出将只有 A 和 B,因为它们都有共同的 sharedWith 字段值 NumberLong(456) 并且没有过期,因为今天的时间(currentTime : 1 July)小于 expiryTime。

注意:如果对于集合 B,currentTime >= expiryTime 表示如果它已过期,那么它不应返回任何输出,因为在这种情况下,不能单独返回文档 A 或 C,因为输出必须包含多个共享文档具有相似的 sharedWith 字段值,即使它没有过期。文档 D 超出范围,因为它从今天的时间 > D 的 expiryTime 开始过期。

如何更新以下查询以实现此目的。非常感谢你

db.getCollection('sharing').aggregate([
  {
    $addFields: { time: { $lt: ["$currentTime", "$expiryTime"] } }
  },
  { 
    $match: { time: true } 
  },

   { $group: { 
        // Group by fields to match on sharedWith
        _id: { sharedWith: "$a"},

        // Count number of matching docs for the group
        count: { $sum:  1 },
    
        // Save the _id for matching docs
        docs: { $push: "$_id" }
    }},
    // Limit results to duplicates (more than 1 match) 
    { $match: {
        count: { $gt : 1 }
    }}
]);

这是最后一个查询,但我认为它不能用作 AND 条件,我只想要那些 sharedWith 值相同且 currentTime 的记录

【问题讨论】:

  • $match 使用$expr$lt 运算符放在$group 阶段上方。
  • 您好,请您提供一些示例,这将非常有帮助
  • 先放这个阶段{ $match: { $expr: { $lt: ["$currentTime", "$expiryTime"] } } }
  • Error: command failed: { "ok" : 0, "errmsg" : "unknown top level operator: $expr", "code" : 2, "codeName" : "BadValue" } : aggregate failed 这是我收到的消息,请帮忙
  • 很高兴您已经解决了您的问题。

标签: mongodb mongodb-query aggregation-framework aggregation


【解决方案1】:

以下查询解决了问题... $unwind 用于将数组拆分为单个字段,以便 $group 在 sharedWith 上工作

db.getCollection('sharing').aggregate([
  { 
    $match: { "expiryTime":{"$gte": ISODate()}  } 
  },
  { $unwind: "$sharedWith"},
  { $group: { 
       // Group by fields to match on sharedWith
       _id: "$sharedWith",

       // Count number of matching docs for the group
       count: { $sum:  1 },

       // Save the _id for matching docs
       docs: { $push: "$_id" }
    }},
    // Limit results to duplicates (more than 1 match) 
    { $match: {
        count: { $gt : 1 }
    }}
]);


【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-24
    • 1970-01-01
    • 1970-01-01
    • 2020-10-02
    相关资源
    最近更新 更多