gpt4 book ai didi

mongodb - 在多个文档上使用 $unwind

转载 作者:IT老高 更新时间:2023-10-28 13:23:23 30 4
gpt4 key购买 nike

这个问题 - Is it possible to get a slice of a slice in Mongo?涵盖了如何在 Mongo 中获取切片。简而言之,使用聚合链来$unwind$skip$limit$unwind$skip$limit$group

我的问题是如何对多个文档的集合执行此操作。我想修剪每个数组中的嵌套数组。但是,一旦我 $unwind$skip$limit 仅根据第一个数组的编号才有意义。

有没有办法在集合中的每个文档上运行这种管道,而不是在整个集合上运行?我希望在聚合管道中做的事情有可能吗?使用 Map-Reduce 显然是可行的,但这样做比单独运行对 $unwind 每个文档的 n+1 个查询要慢。


编辑

以下是示例记录。

{
title: "Text Title"
vtitle: "Text Version Title"
text: [[["Book1, Chapter 1, Line 1", "Book1, Chapter 1, Line 2"],["Book 1, Chapter 2, Line 1"]],[["Book 2, Chapter 1, Line 1]]]
}

这里的记录是一本大书的文本,存储为深度为 3 的数组。同一个title可以有很多不同的vtitletext可以很大。

我想从许多书籍的集合中的每本书中选择一小部分包含的文本,由索引标识 - 每个返回的单个文档的切片的切片。

例如,[3,3] 的输入参数会返回如下记录:

{ "text" : ["Book 4, Chapter 4, Line 1", "Book 4, Chapter 4, Line 2", ...] }

最佳答案

TL;博士

我认为简短的回答是你还不能真正做你想做的事。当前的选项是等到 v3.1 或使用 group 聚合来破解它(但我怀疑这对您的需求来说太慢了)。

理由

虽然不太清楚您想要获得的确切结果,但目的显然是您希望能够在您的集合中找到一组匹配的文档并转换(即映射)文档(通过切片嵌套数组生成一个平面的字符串列表)。搜索是无关紧要的,因为您可以在映射之前或之后进行,并且仍然满足您的约束。因此,我将只讨论映射。

这是 MapReduce 的自然用例,但您已明确将其排除在允许的答案之外。因此,有 3 个选项,我将依次选择。

1) 查询

由于您已禁止多个查询,因此您唯一的选择是在请求中映射数据。这是通过 the projection operators 处理的。 .这些都行不通。

  1. 虽然这里有一个 $slice 运算符,但它不处理嵌套数组。
  2. $ 运算符仅允许您获取数组中的第一个条目,这也不足以获取数组中的任意位置。
  3. $elemMatch 只允许您从数组中获取一个字段 - 这也不足以满足您的需求。

此外,您不能在查询中链接投影,因此您不能以某种巧妙的方式将多个投影放在一起以多次切片数据。

简而言之,这是行不通的。

2) 聚合管道

不幸的是,在 v3.1 之前,聚合管道还没有切片运算符。 .因此,您仅限于 $project或者可能巧妙地使用其他运算符(根据您链接的文章)。

先取投影算子。虽然你可以operate on array fields ,您现在只能获得尺寸。您可以尝试使用 set logic但这本质上是无序的,因此您无法在此处获得第 N 个条目。

因此,直接操作显然不起作用。那么我们可以增强您链接的文章吗?此解决方法仅适用于一个文档,因为您不需要区分多个文档。因此,您可以展开数组以创建更大的文档列表,然后使用文档级别的范围操作来有效地进行切片。

遗憾的是,当您需要在最新的展开列表中找到下一个原始文档的开始时,这会失败。没有 operators 的组合这允许您枚举展开的数组,然后在该枚举和原始文档上进行选择。

  1. $unwind 扩展数组,但没有为您提供随后匹配的索引,并且 $skip 无法跳到具有匹配条件的下一个文档。
  2. $redact 仍将您保留在原始文档的范围内,但随后会遇到与 $project 相同的问题,即它无法对嵌套数组进行操作。

简而言之,这也是一场破产。

3) 组聚合

此时我正要放弃,然后我注意到group aggregation .您可以为匹配的文档创建一个过滤器,然后提供一个带有 finalize 的任意 JavaScript 函数来在返回之前转换该数据。这意味着您应该能够发出这样的命令:

db.runCommand(
{
group:
{
ns: 'books',
key: { title: 1, text: 1 },
cond: { },
$reduce: function (curr, result) { },
initial: { },
finalize: function(result) {
// Insert your code here to slice the array - e.g.
result.text = result.text[0][0]
}
}
})

当然,正如 here 所记录的那样如果您的数据库是分片的、您的结果大于 16MB 或者您有超过 20,000 个文档(因为现在每个文档都是聚合的键),这将不起作用。当数据集变大时也很慢。

关于mongodb - 在多个文档上使用 $unwind,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31299425/

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