mongodb聚合查找管道匹配$lte

fumotvh3  于 2023-03-01  发布在  Go
关注(0)|答案(1)|浏览(130)

我需要一点帮助来理解如何在查找管道中进行匹配。这里是我的聚合。

{$match: {$and: [
    {pairAddress: '0x8968cebff66c1188fbB28a7F6F2F0994a8aB3Be2'},
    {$or: [
        {timestamp: {$lte: 0, $ne: 0}},
        {timestamp: {$gte: 0}}
    ]}
]}},

{$addFields:{
    timestampBoundary: {
        $subtract: [
            "$timestamp",
            {$mod: ["$timestamp", 60]}
        ]
    },
}},

{$sort: {timestamp: 1}},

{$group:{
    _id: "$timestampBoundary",
    quoteTokenDecimals: {$last: "$quoteTokenDecimals"},
    base0: {$last: "$base0"},
    high: {$max: "$price"},
    low: {$min: "$price"},
    open: { $first: "$price" },
    close: { $last: "$price" },
    lastTime: {$last: "$timestamp"},
    amount: {
        $sum: {
            $cond: [
                { $eq: ["$base0", true] },
                {$toDecimal: "$amount1"},
                {$toDecimal: "$amount0"}
            ]
        }
    },
    stable: {$last: "$stable"},
}},

{$lookup:{
    from: "BASEPRICE_BSC",
    let:{ timestampBoundary: "$timestampBoundary" },
    pipeline: [
        {$match: {
            $expr: {
                $lte: ["$timestampBoundary", "$$timestampBoundary"]
            }
        }},
        {$sort: { timestamp: 1 }},
        {$limit: 1},
        {$project: { _id: 0, price: 1}}
    ],
    as: "lookupResult"
}},

{$addFields:{
    conversionRate: {
      $cond: [
        { $eq: [{ $size: "$lookupResult" }, 0] },
        { $arrayElemAt: ["$lookupResult", -1] },
        { $arrayElemAt: ["$lookupResult", 0] }
      ]
    }
}},

{$project: {
    txs: 1,
    quoteTokenDecimals: 1,
    base0: 1,
    open: 1,
    high: 1,
    low: 1,
    close: 1,
    amount: 1,
    stable: 1,
    conversionRate: "$conversionRate.price"
}}

我的聚合创建烛台日期从交易。开盘价,收盘价,最高价和最低价是相对价格对。我有另一个收集,我保存转换率(BASEPRICE_BSC)我遇到的问题是,对于每个蜡烛,没有与baseprice集合中的时间戳完全匹配的。我需要它找到最近的较低时间戳并将其用作baseprice,但我没法让它工作。
我不完全理解的是查找管道中的变量,然后是$expr with $lte数组。
我知道我想创建查找中匹配“lastTime”时间戳小于或等于的所有时间戳的数组,按降序分组排序并返回第一个值。但我不知道也找不到关于let变量的确切功能或如何从管道中的查找集合中选择字段的任何信息。

vsaztqbk

vsaztqbk1#

似乎聊天ai变得更好,然后使用堆栈溢出。经过3天的搜索和测试,我终于得到了我需要的信息。
首先,在组中添加新字段“lastTime”,其表示组中的最高编号时间戳。
然后在查找中,我将其设置为外部变量,并且可以匹配timestamp大于或等于lasTime的位置。
这将总是返回一个最接近我需要的时间戳的基本价格。

{$match: {$and: [
    {pairAddress: '0x8968cebff66c1188fbB28a7F6F2F0994a8aB3Be2'},
    {$or: [
        {timestamp: {$lte: 0, $ne: 0}},
        {timestamp: {$gte: 0}}
    ]}
]}},

{$addFields:{
    timestampBoundary: {
        $subtract: [
            "$timestamp",
            {$mod: ["$timestamp", 60]}
        ]
    },
}},

{$sort: {timestamp: 1}},

{$group:{
    _id: "$timestampBoundary",
    quoteTokenDecimals: {$last: "$quoteTokenDecimals"},
    base0: {$last: "$base0"},
    high: {$max: "$price"},
    low: {$min: "$price"},
    open: { $first: "$price" },
    close: { $last: "$price" },
    lastTime: {$last: "$timestamp"},
    amount: {
        $sum: {
            $cond: [
                { $eq: ["$base0", true] },
                {$toDecimal: "$amount1"},
                {$toDecimal: "$amount0"}
            ]
        }
    },
    stable: {$last: "$stable"},
}},

{$lookup:{
    from: "BASEPRICE_BSC",
    let:{ lastTime: "$lastTime" },
    pipeline: [
        {$match: {
            $expr: {
                $gte: ["$timestamp", "$$lastTime"]
            }
        }},
        {$sort: { timestamp: 1}},
        {$limit: 1},
        {$project: { _id: 0, price: 1, timestamp: 1}}
    ],
    as: "lookupResult"
}},

{$addFields: {
    conversionRate: { $arrayElemAt: ["$lookupResult.price", 0] }
}},

{$project: {
    txs: 1,
    quoteTokenDecimals: 1,
    base0: 1,
    open: 1,
    high: 1,
    low: 1,
    close: 1,
    amount: {
        $toString: {
          $divide: [
            { $toDecimal: "$amount" },
            { $pow: [10, "$quoteTokenDecimals"] }
          ]
        }
    },
    stable: 1,
    conversionRate: 1,
    pairAddress: pairAddress,
}}

从chatGPT我得到了大部分的解决方案,但不了解查找管道是如何工作的,let:{ lastTime:“$lastTime”},我们创建了一个变量,该变量的值来自查找外部,我们可以使用它在查找内部进行比较。我们需要在匹配内部使用$expr来比较查找内部的字段。

相关问题