在MongoDB 4.2中,按天向N个重置次数最多的文档中添加新字段

问题描述 投票:0回答:1

我有一个包含计划的文件:

{ _id: ObjectId, userId: ObjectId, marker: string, datetime: Date, etc... }

这是绑定到用户(marker)的标记(userId)的集合。装订日期存储在datetime字段中。

每天用户可以接收任意数量的标记。

[当我从此集合中获取数据时,我需要添加一个名为allowed且类型为boolean的额外字段,并且仅当该记录位于日历的N个最近期记录中时,此字段才必须为true用户的一天。

例如,如果初始集合看起来像这样,并且N == 2

{_id: ..., userId: "a", marker: "m1", datetime: "2020-01-01.10:00"}
{_id: ..., userId: "a", marker: "m2", datetime: "2020-01-02.10:00"}
{_id: ..., userId: "a", marker: "m3", datetime: "2020-01-02.11:00"}
{_id: ..., userId: "a", marker: "m4", datetime: "2020-01-02.12:00"}
{_id: ..., userId: "a", marker: "m5", datetime: "2020-01-02.13:00"}
{_id: ..., userId: "b", marker: "m1", datetime: "2020-01-01.10:00"}
{_id: ..., userId: "b", marker: "m2", datetime: "2020-01-01.11:00"}
{_id: ..., userId: "b", marker: "m3", datetime: "2020-01-01.13:00"}
{_id: ..., userId: "b", marker: "m4", datetime: "2020-01-02.11:00"}
{_id: ..., userId: "b", marker: "m5", datetime: "2020-01-02.12:00"}
{_id: ..., userId: "b", marker: "m6", datetime: "2020-01-03.10:00"}

然后,最终结果应如下所示:

{_id: ..., userId: "a", marker: "m1", datetime: "2020-01-01.10:00", allowed: true}
{_id: ..., userId: "a", marker: "m2", datetime: "2020-01-02.10:00", allowed: true}
{_id: ..., userId: "a", marker: "m3", datetime: "2020-01-02.11:00", allowed: true}
{_id: ..., userId: "a", marker: "m4", datetime: "2020-01-02.12:00", allowed: false}
{_id: ..., userId: "a", marker: "m5", datetime: "2020-01-02.13:00", allowed: false}
{_id: ..., userId: "b", marker: "m1", datetime: "2020-01-01.10:00", allowed: true}
{_id: ..., userId: "b", marker: "m2", datetime: "2020-01-01.11:00", allowed: true}
{_id: ..., userId: "b", marker: "m3", datetime: "2020-01-01.13:00", allowed: false}
{_id: ..., userId: "b", marker: "m4", datetime: "2020-01-02.11:00", allowed: true}
{_id: ..., userId: "b", marker: "m5", datetime: "2020-01-02.12:00", allowed: true}
{_id: ..., userId: "b", marker: "m6", datetime: "2020-01-03.10:00", allowed: true}

我正在使用MongoDB 4.2。

mongodb mongodb-query aggregation-framework
1个回答
0
投票

查询1:

db.markers.aggregate([ /** group docs based on userId & date(2020-01-01), push all matched docs to data */ { $group: { _id: { userId: '$userId', datetime: { $arrayElemAt: [{ $split: ["$datetime", "."] }, 0] } }, data: { $push: '$$ROOT' } } }, /** Re-forming data field with added new field allowed for only docs where criteria is met */ { $addFields: { data: { $map: { input: "$data", as: "each", /** conditional check to add new field on only docs which are 0 & 1 position of array */ in: { $cond: [{ $lte: [{ $indexOfArray: ["$data", '$$each'] }, 1] }, { $mergeObjects: ['$$each', { allowed: true }] }, { $mergeObjects: ['$$each', { allowed: false }] }] } } } } }, /** unwind data */ { $unwind: '$data' }, /** making data object as root level doc */ { $replaceRoot: { newRoot: "$data" } }])

查询2:

db.markers.aggregate([ { $group: { _id: { userId: '$userId', datetime: { $arrayElemAt: [{ $split: ["$datetime", "."] }, 0] } }, data: { $push: '$$ROOT' } } }, { $addFields: { data: { $map: { input: "$data", as: "each", in: { $cond: [{ $or: [{ $eq: [{ $arrayElemAt: ["$data", -1] }, '$$each'] }, { $eq: [{ $arrayElemAt: ["$data", -2] }, '$$each'] }] }, { $mergeObjects: ['$$each', { allowed: true }] }, { $mergeObjects: ['$$each', { allowed: false }] }] } } } } }, { $unwind: '$data' }, { $replaceRoot: { newRoot: "$data" } }])

Query1
将起作用并为您提供结果,但假设有问题的数据是示例数据,并且当您查看集合时将实时进行userId: "a", marker: "m5"将是第一个文档,就好像该集合具有连续的数据写入然后最新文档将具有最新的data time,因此

Query1的索引0或1将不起作用,但是在这里Query2将起作用。如果标记集合具有与所给定的完全相同的有序数据,则可以使用Query1Note:

对于

Query2-我们可以使用Query1的相同逻辑,即仅当执行$sortdateTime时才检查索引(0,1)而不是对象比较。 ]字段,没有走那条路线是因为在一个字段上对整个集合进行排序比这没有效率。

© www.soinside.com 2019 - 2024. All rights reserved.