填写记录中的缺失日期

时间:2018-09-08 11:49:38

标签: node.js mongodb mongoose aggregation-framework aggregation

我收藏了class FileHelper { public static string saveLocation; public static SpreadsheetDocument spreadsheetDoc; public static async void GetFileAsync() { var (authResult, message) = await Authentication.AquireTokenAsync(); var httpClient = new HttpClient(); HttpResponseMessage response; var request = new HttpRequestMessage(HttpMethod.Get, MainPage.fileurl); request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", authResult.AccessToken); response = await httpClient.SendAsync(request); byte[] fileBytes = await response.Content.ReadAsByteArrayAsync(); StorageLibrary videoLibrary = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Videos); string saveFolder = videoLibrary.SaveFolder.Path; string saveFileName = App.Date + "-" + App.StartTime + "-" + App.IBX + "-" + App.Generator + ".xlsx"; saveLocation = saveFolder + "\\" + saveFileName; using (MemoryStream stream = new MemoryStream()) { stream.Write(fileBytes, 0, (int)fileBytes.Length); using (spreadsheetDoc = SpreadsheetDocument.Open(stream, true)) { UpdateCell(spreadsheetDoc, App.Date, 2, "D"); await Task.Run(() => { File.WriteAllBytes(saveLocation, stream.ToArray()); }); } } } public static void UpdateCell(SpreadsheetDocument docName, string text, uint rowIndex, string columnName) { WorksheetPart worksheetPart = GetWorksheetPartByName(spreadsheetDoc, "GenRun"); if (worksheetPart != null) { Cell cell = GetCell(worksheetPart.Worksheet, columnName, rowIndex); cell.CellValue = new CellValue(text); cell.DataType = new EnumValue<CellValues>(CellValues.String); } } private static WorksheetPart GetWorksheetPartByName(SpreadsheetDocument document, string sheetName) { IEnumerable<Sheet> sheets = document.WorkbookPart.Workbook.GetFirstChild<Sheets>(). Elements<Sheet>().Where(s => s.Name == sheetName); if (sheets.Count() == 0) { return null; } string relationshipId = sheets.First().Id.Value; WorksheetPart worksheetPart = (WorksheetPart) document.WorkbookPart.GetPartById(relationshipId); return worksheetPart; } private static Cell GetCell(Worksheet worksheet, string columnName, uint rowIndex) { Row row = GetRow(worksheet, rowIndex); if (row == null) return null; return row.Elements<Cell>().Where(c => string.Compare (c.CellReference.Value, columnName + rowIndex, true) == 0).First(); } private static Row GetRow(Worksheet worksheet, uint rowIndex) { return worksheet.GetFirstChild<SheetData>(). Elements<Row>().Where(r => r.RowIndex == rowIndex).First(); } }

产品视图

ProductViews

我有一个查询,用于获取特定产品的每日视图。

查询

{
    productId: '5b8c0f3204a10228b00a1745,
    createdAt: '2018-09-07T17:18:40.759Z',
}

当前结果

ProductView.aggregate([
    { $match: { productId } },
    { $project: { day: { $substr: ["$createdAt", 0, 10] } } },
    {
        $group: {
            _id: "$day",
            count: { $sum: 1 },
            time: { $avg: "$createdAt" },
        }
    },
    { $sort: { _id: 1 } },
    {
        $project: {
            date: '$_id',
            views: '$count',
        },
    },
]).exec((err, result) => ...)

问题

问题是,这种聚合在具有[ { date: '2018-09-01', views: 1 }, { date: '2018-09-02', views: 3 }, { date: '2018-09-04', views: 2 }, { date: '2018-09-05', views: 5 }, // ... ] 视图的情况下不会返回{ date: '2018-09-03', views: 0 }。这会导致数据显示不正确:enter image description here

结果应类似于

0

P.S .:最好输入开始日期和结束日期以根据此范围输出结果

3 个答案:

答案 0 :(得分:2)

您的问题类似于来自2014的帖子。

该帖子中提供的所有答案都是有效的,如果您可以在应用程序代码中生成缺少的日期,则会更简单。

自从您要求mongodb解决方案以来,自2014年以来发生了很多变化,所以我创建了一个新的聚合管道,可用于3.6版本。

user

答案 1 :(得分:2)

我建议您添加缺少日期的客户端(如果只有一两个)并且要处理的文档数量很少。

话虽如此,以下管道仅适用于MongoDB 4.0+,但稍作努力,我们就可以使其在3.6中工作。

[
    {
        $group: {
            _id: null,
            dates: {
                $push: {
                    $let: {
                        vars: {
                            date: {
                                $dateToParts: {
                                    date: {
                                        $toDate: "$createdAt"
                                    }
                                }
                            }
                        },
                        in: {
                            $toDouble: {
                                $dateFromParts: {
                                    year: "$$date.year",
                                    month: "$$date.month",
                                    day: "$$date.day"
                                }
                            }
                        }
                    }
                }
            }
        }
    },
    {
        $addFields: {
            startDate: {
                $divide: [
                    {
                        $min: "$dates"
                    },
                    1000
                ]
            },
            endDate: {
                $divide: [
                    {
                        "$max": "$dates"
                    },
                    1000
                ]
            }
        }
    },
    {
        $addFields: {
            dates: {
                $map: {
                    input: {
                        $concatArrays: [
                            "$dates",
                            {
                                $setDifference: [
                                    {
                                        $map: {
                                            input: {
                                                $range: [
                                                    {
                                                        $toDouble: "$startDate"
                                                    },
                                                    {
                                                        $toDouble: "$endDate"
                                                    },
                                                    24*60*60
                                                ]
                                            },
                                            in: {
                                                $multiply: [
                                                    "$$this",
                                                    1000
                                                ]
                                            }
                                        }
                                    },
                                    "$dates"
                                ]
                            }
                        ]
                    },
                    in: {
                        $toDate: "$$this"
                    }
                }
            }
        }
    },
    {
        "$unwind": "$dates"
    },
    {
        "$group": {
            _id: "$dates",
            views: {
                $sum: 1
            }
        }
    },
    {
        "$sort": {
            _id: -1
        }
    }
]

答案 2 :(得分:1)

您需要几个附加步骤来返回默认值。首先,您需要使用$group设置为_id的{​​{1}}来收集一个文档中的所有结果。然后,您可以将$map与一系列天配合使用。在该null内,您可以使用$indexOfArray查找当前结果集中是否存在该日期。如果是($map,则可以返回该值,否则需要返回将index != -1设置为views的默认子文档。然后,您可以使用$unwind返回文档列表,并使用$replaceRoot将嵌套的0提升到顶层。

stats

您可以使用简单循环在应用程序逻辑中生成静态日期列表。我相信在MongoDB中也可以(使用$range),但这可能会使聚合管道复杂化。让我知道您是否满意,或者想尝试在MongoDB中生成该日期数组。