mongodb - 有没有更好的方法在 mongodb 文档中的索引之后对数组字段进行切片?
问题描述
我的文档中有一个订单字段,其中包含另一个集合中文档的参考 ID。
product: {
_id: // product id,
orders: [refId_1415, refId_5414, refId_0210, refId_4320, refId_1543, refId_4326, refId_7845]
}
由于它们不是按升序/降序排列的,因此我无法真正运行 $gt 或 $lt 来检索值。因此,我必须在用户给出某个 refId 之后获取所有 refId。假设 refId_5414 是用户给出的。因此,从索引 2 (refId_0210) 开始运行 $lookup 以返回一个数组,其中填充的值如下所示:
order_history: [{
id: refId_0210,
created: // Date
},
{
id: refId_4320,
created: // Date
},
...
{
id: refId_7845,
created: // Date
}];
这是我提出的查询并且它有效,但是有很多阶段,我想知道是否有更好的方法来做到这一点:
- 查找具有 id 的产品。
{
$match: { _id: product._id },
},
- 找到所需起始索引之前的 id 索引,因为这就是我们将收到的。
{
$project: {
index: {
$indexOfArray: ["$orders", "refId_5414"],
},
orders: 1,
},
},
- 将上一阶段的索引增加 1 以获得所需的起始索引。
{
$project: {
index: { $add: ["$index", 1] },
orders: 1,
},
},
- 将数组从起始索引切片到给定索引。
{
$project: {
orders: { $slice: ["$orders", "$index", to] },
_id: 0,
},
},
- 重新填充数组
{
$lookup: {
from: "orders",
let: { orders: "$orders" },
pipeline: [{ $match: { $expr: { $in: ["$_id", "$$orders"] } } }],
as: "order_history",
},
},
这是它的外观(注意 3 个项目阶段):
const res = await this.collection.aggregate([
{
$match: { _id: product._id },
},
{
$project: {
...
},
},
{
$project: {
...
},
},
{
$project: {
...
},
},
{
$lookup: {
...
},
},
])
任何使它变得更好的建议将不胜感激。谢谢你。
解决方案
您的查询看起来不错,您可以减少多个$project
阶段并使用简单的查找:
{ $match: { _id: 1 } },
{
$project: {
_id: 0,
orders: {
$slice: [
"$orders",
{
$add: [
{ $indexOfArray: ["$orders", "refId_5414"] },
1
]
},
to
]
}
}
},
{
$lookup: {
from: "orders",
localField: "orders",
foreignField: "id",
as: "orders"
}
},
{ $project: { orders: "$orders.id" } }
推荐阅读
- node.js - Node.js 后端/服务器:在“新函数”实例中无法“要求”
- python - 在 python 函数中执行 bash 命令行
- python - 为什么我在 Python 上使用 BackTrader 会收到此错误?
- spring-mvc - 如何使用 ResponseEntity 从我的 REST 调用中返回简单的错误消息?
- javascript - Angular 的订阅未记录完整错误
- python - keras,无效的预测大小
- java - 如何使 Spring Projections 与 @OneToOne 关系一起工作?
- react-native - 使用 React Navigation 防止在选项卡更改时重新渲染
- r - 在 R 中绘制 geom_line 和 geom_ribbon 时如何添加不连续性?
- regex - 修改 Go 正则表达式,使其不拾取最后一个字符