MongoDB如何选择嵌入字段的$ max

时间:2018-08-09 00:13:59

标签: mongodb mongodb-query aggregation-framework

我正在尝试获取记录详细信息,但我希望在嵌入字段中最近的日期
(类似于SQL中的max)。

在下面的数据中,最近的操作事件是"Date""2017-10-18 15:36:00"

我想从收藏集中返回(收藏名称为 subs ):

_id , EmailAddress , CustomFields-和最近的动作记录 (或null(无操作记录))

理想情况下,我也想过滤列表,例如最近一次操作> 01 Jan 2014

{
  "EmailAddress": "joe@example.com",
  "Name": "",
  "Date": "2009-01-23 06:22:00",
  "State": "Active",
  "CustomFields": [
    {
      "Key": "[FirstName1]",
      "Value": "Joe"
    },
    {
      "Key": "[LastName1]",
      "Value": "Bloggs"
    }
  ],
  "ReadsEmailWith": "Gmail",
  "ConsentToTrack": "",
  "history": [
    {
      "ID": "d5e593987eab28595bafa1893fe3ddd6",
      "Type": "Campaign",
      "Name": "Retail 18th October 2017",
      "Actions": [
        {
          "Event": "Click",
          "Date": "2017-10-18 15:36:00",
          "IPAddress": "101.187.99.233",
          "Detail": "http://www.example.com"
        },
        {
          "Event": "Open",
          "Date": "2017-10-18 15:36:00",
          "IPAddress": "101.187.99.233",
          "Detail": ""
        }
      ]
    },
    {
      "ID": "ab46afa75b85f2eacdf8584c2287f844",
      "Type": "Campaign",
      "Name": "August 2010",
      "Actions": [
        {
          "Event": "Click",
          "Date": "2010-08-30 15:20:00",
          "IPAddress": "",
          "Detail": "http://www.example.com"
        },
        {
          "Event": "Open",
          "Date": "2010-08-30 15:20:00",
          "IPAddress": "",
          "Detail": ""
        },
        {
          "Event": "Open",
          "Date": "2010-08-30 14:28:00",
          "IPAddress": "",
          "Detail": ""
        }
      ]
    },
    {
      "ID": "1e414ee3554008ce93fa5087f7376923",
      "Type": "Campaign",
      "Name": "July 2010",
      "Actions": [
        {
          "Event": "Open",
          "Date": "2010-07-26 15:24:00",
          "IPAddress": "",
          "Detail": ""
        }
      ]
    }
  ]
}

2 个答案:

答案 0 :(得分:2)

您可以在3.4中使用以下汇总来获取日期最高的Action元素。

db.col.aggregate({"$project":{
  "maxEle":{
    "$reduce":{
      "input":"$history.Actions",
      "initialValue":{"Date":""},
      "in":{
        "$cond":[
          {"$gt":[{"$max":"$$this.Date"},"$$value.Date"]},
          {"$arrayElemAt":["$$this",{"$indexOfArray":["$$this",{"$max":"$$this.Date"}]}]},
          "$$value"
        ]
      }
    }
  }
}})

答案 1 :(得分:1)

您可以尝试以下汇总:

db.subs.aggregate([
    {
        $project: {
            _id: 1,
            EmailAddress: 1,
            CustomFields: 1,
            MostRecentActionRecord: {
                $reduce: {
                    input: {
                        $reduce: {
                            input: {
                                $map: {
                                    input: "$history",
                                    as: "h",
                                    in: "$$h.Actions"
                                }
                            },
                            initialValue: [],
                            in: { $concatArrays: [ "$$value", "$$this" ] }
                        }
                    },
                    initialValue: null,
                    in: {
                        $cond: {
                            if: { $and: [ { $gt: [ "$$this.Date", "2014-01-01 00:00:00" ] }, { $gt: [ "$$this.Date", "$$value.Date" ] } ] },
                            then: "$$this",
                            else: "$$value"
                        }
                    }
                }
            }
        }
    }
])

使用$map和内部$reduce可将Actions展平为单个数组。然后,您可以再次将$reduce$cond一起使用,以获取最新值,包括您的病情。将null设置为初始值将导致null在不匹配的情况下返回