gpt4 book ai didi

mongodb - 如何使用组和累加器阶段改进 MongoDB 聚合?

转载 作者:行者123 更新时间:2023-12-04 08:05:34 27 4
gpt4 key购买 nike

查询如下:

  • 将选定的文档与匹配项匹配
  • 按月中的某天分组,然后使用累加器将 URL 和计数添加到返回的数据集中

  • 问题是查询非常复杂,随着数据量的增长,这似乎真的不是很好的性能。在 mongodb 中是否有更简单的方法来实现相同的目标?
    输出形状如下所示:
    {
    "results": [
    {
    "_id": {
    "month": 2,
    "day": 2,
    "year": 2021
    },
    "urls": [
    {
    "url": "https://shop.mydomain.com/product/golden-axe",
    "count": 20
    },
    {
    "url": "https://shop.mydomain.com/product/phantasy-star",
    "count": 218
    },
    {
    "url": "https://shop.mydomain.com/product/sega-arcades-retro",
    "count": 30
    }
    ],
    "count": 268
    },
    {
    "_id": {
    "month": 2,
    "day": 3,
    "year": 2021
    },
    "urls": [
    {
    "url": "https://shop.mydomain.com/product/golden-axe",
    "count": 109
    },
    {
    "url": "https://shop.mydomain.com/product/phantasy-star",
    "count": 416
    },
    {
    "url": "https://shop.mydomain.com/product/sega-arcades-retro",
    "count": 109
    }
    ],
    "count": 634
    },
            const aggregate = [
    {
    $match: {
    source: 'itemLineView',
    createdAt: {
    $gte: new Date(query.dateGT),
    $lte: new Date(query.dateLT)
    },
    url: { $regex: `^${query.url}` },
    }
    },
    {
    $group: {
    _id: {
    month: {
    $month: '$createdAt'
    },
    day: {
    $dayOfMonth: '$createdAt'
    },
    year: {
    $year: '$createdAt'
    }
    },
    urls: {
    // https://docs.mongodb.com/manual/reference/operator/aggregation/accumulator/#grp._S_accumulator
    $accumulator: {
    init: function (): AccumulatorSourceStats {
    return {
    origins: []
    };
    },
    // initArgs: [], // Argument arr to pass to the init function
    accumulate: function (state: AccumulatorSourceStats, url: string) {
    const index = state.origins.findIndex(function (origin) {
    return origin.url === url;
    });
    if (index === -1) {
    state.origins.push({
    url: url,
    count: 1
    });
    } else {
    ++state.origins[index].count;
    }
    return state;
    },

    accumulateArgs: ['$url'], // Argument(s) passed to the accumulate function

    merge: function (state1: AccumulatorSourceStats, state2: AccumulatorSourceStats) {
    return {
    origins: state1.origins.concat(state2.origins)
    };
    },

    finalize: function (state: AccumulatorSourceStats) { // Adjust the state to only return field we need
    const sortByUrl = function (a: AccumulatorSourceStatsOrigin, b: AccumulatorSourceStatsOrigin) {
    if (a.url < b.url) {
    return -1;
    }
    if (a.url > b.url) {
    return 1;
    }
    return 0;
    };
    return state.origins.sort(sortByUrl);
    },

    lang: 'js'
    }
    },
    count: { $sum: 1 }
    }
    },
    { $sort: { _id: 1 } }
    ];
    return this.model.aggregate(aggregate);

    最佳答案

    来自 docs :

    Executing JavaScript inside of an aggregation operator may decrease performance. Only use the $accumulator operator if the provided pipeline operators cannot fulfill your application’s needs.


    避免在 Mongo 管道中使用 javascript 代码被认为是一种很好的做法,这应该仅用作最后的手段。在这种情况下,我们可以通过 $group 避免使用它ing 两次,每个 url 每天一次,然后每天一次。像这样:
    db.collection.aggregate([
    {
    $match: {
    source: "itemLineView",
    createdAt: {
    $gte: new Date(query.dateGT),
    $lte: new Date(query.dateLT)
    },
    url: {
    $regex: `^${query.url}`
    },

    }
    },
    {
    $group: {
    _id: {
    month: {
    $month: "$createdAt"
    },
    day: {
    $dayOfMonth: "$createdAt"
    },
    year: {
    $year: "$createdAt"
    },
    url: "$url"
    },
    count: {
    $sum: 1
    }
    }
    },
    {
    $group: {
    _id: {
    month: "$_id.month",
    day: "$_id.day",
    year: "$_id.year",

    },
    urls: {
    $push: {
    url: "$_id.url",
    count: "$count"
    }
    },
    count: {
    $sum: "$count"
    }
    }
    }
    ])
    Mongo Playground

    关于mongodb - 如何使用组和累加器阶段改进 MongoDB 聚合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66238673/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com