Mongo aggregate guidance

Viewed 23

I need some guidance please.

I have a data structure that looks like this (note that the certResults field is an array, in this case - apple.com and reuters.com, but typically there are more results within the certResults array):

{
    "deviceTag": "",
    "clientHostName": "555317e186a0",
    "dataFormatVersion": 10,
    "certResults":
    [
        {
            "hostname": "apple.com",
            "port": 443,
            "startTime": "2022/07/01 03:50:57.867716",
            "endTime": "2022/07/01 03:50:57.960064",
            "queryTime": 92.35,
            "certificateInfo":
            {
                "subject":
                {
                    "countryName": "US",
                    "stateOrProvinceName": "California",
                    "localityName": "Cupertino",
                    "organizationName": "Apple Inc.",
                    "commonName": "apple.com"
                },
                "certificateIssuer":
                {
                    "countryName": "US",
                    "organizationName": "Apple Inc.",
                    "commonName": "Apple Public EV Server ECC CA 1 - G1"
                },
                "version": 3,
                "serialNumber": "6A1D3FA84A43C329F1051060FF4698BA",
                "notBefore": "Apr 26 21:58:37 2022 GMT",
                "notAfter": "May 26 21:58:36 2023 GMT",
                "OCSP":
                [
                    "http://ocsp.apple.com/ocsp03-apevsecc1g101"
                ],
                "crlDistributionPoints":
                [
                    "http://crl.apple.com/apevsecc1g1.crl"
                ],
                "caIssuers":
                [
                    "http://certs.apple.com/apevsecc1g1.der"
                ],
                "subjectAltName":
                {
                    "DNS0": "apple.com"
                }
            },
            "timeLeft": "10 months, 25 days, 18 hours, 7 minutes, 39 seconds",
            "percentageUtilization": 16.52
        },
        {
            "hostname": "reuters.com",
            "port": 443,
            "startTime": "2022/07/01 03:50:57.962692",
            "endTime": "2022/07/01 03:50:58.271235",
            "queryTime": 308.54,
            "certificateInfo":
            {
                "subject":
                {
                    "commonName": "reuters.com"
                },
                "certificateIssuer":
                {
                    "countryName": "US",
                    "organizationName": "Let's Encrypt",
                    "commonName": "R3"
                },
                "version": 3,
                "serialNumber": "04203F2F15F8194772481DABC1061E213EAB",
                "notBefore": "Jun  6 12:54:06 2022 GMT",
                "notAfter": "Sep  4 12:54:05 2022 GMT",
                "OCSP":
                [
                    "http://r3.o.lencr.org"
                ],
                "caIssuers":
                [
                    "http://r3.i.lencr.org/"
                ],
                "subjectAltName":
                {
                    "DNS0": "reuters.com"
                }
            },
            "timeLeft": "2 months, 3 days, 9 hours, 3 minutes, 7 seconds",
            "percentageUtilization": 27.36
        }
    ]
}

This data structure is similar in that it is executed every hour for the same hosts - i.e. each document is the same with updated results in the certResults array.

I'm struggling with the syntax for MongoDB aggregate function.

Using MongoDB's find function, I can collate entries for a specific host by first filtering the dataFormatVersion:10 and then looking at the certResults.hostname field for "reuters.com":

db.certCollection.find({ dataFormatVersion:10, certResults: {$elemMatch: {hostname: "reuters.com"}} }, {_id: 0, certResults: {"hostname.$": 1, "startTime": 1 ,  "port": 1, "percentageUtilization": 1 }} );

Which presents this information:

{ "certResults" : [ { "hostname" : "reuters.com", "port" : 443, "startTime" : "2022/06/28 16:31:49.919962", "percentageUtilization" : 24.61 } ] }
{ "certResults" : [ { "hostname" : "reuters.com", "port" : 443, "startTime" : "2022/06/28 16:34:55.868512", "percentageUtilization" : 24.61 } ] }
{ "certResults" : [ { "hostname" : "reuters.com", "port" : 443, "startTime" : "2022/06/28 16:57:38.926443", "percentageUtilization" : 24.63 } ] }
{ "certResults" : [ { "hostname" : "reuters.com", "port" : 443, "startTime" : "2022/06/28 17:00:02.359976", "percentageUtilization" : 24.63 } ] }

etc.

I'm not sure how to aggregate data for the percentageUtilization field.

I'd like to find out the average for the percentageUtilization field across the responding documents for this hostname "reuters.com" only. Is there a way to filter on startTime and endTime fields as well?

Similarly, I'd like to find out the average percentageUtilization across all host entries for all responding documents (i.e. reuters.com and apple.com) within a certain timeframe (based on startTime and endTime fields).

Any help would be greatly appreciated!

Thank you!

1 Answers

Aha! The trick I was looking for was to use $unwind for the certResults array.

Related