代码之家  ›  专栏  ›  技术社区  ›  Corentin

如何在Mongo中过滤数百万个文档

  •  0
  • Corentin  · 技术社区  · 2 年前

    我试图过滤数百万份文件。每个文档的大小约为7kB。 目前,我最多筛选8个(已定义)字段,但稍后会添加更多字段。

    过滤器可以是任何东西,比如:

    • “字段”:“值”
    • 字段:{“$gte”:值}
    • “field”:{“$regex”:“regexp”}
    • “字段”:{“$in”:[…]}
    • 等。。。

    我希望它很快。所以我创建了索引。 但我不知道我是否需要创建所有可能的索引。 例子: 对于字段a、b、c、d、e、f、g、h:

    • 我应该用所有这些字段创建一个复合索引吗?
    • 或者创建索引的每个组合:
      • a ____ b
      • [...]
      • b、 e、g、h
      • 等。。。

    这样做的问题是,你的索引限制在64个。

    但即使有正确的索引,搜索有时也需要很长时间。

    我还有一个对象的通配符索引。我试图用这个通配符索引创建一个复合索引,但从未使用过。因此,当我在普通过滤器+具有通配符索引的过滤器上搜索时,查询速度非常慢。

    有没有一种解决方案可以在没有索引或性能问题的情况下拥有更多可过滤字段? 也许用所有这些过滤器创建一个较小的集合?为每个过滤器创建一个集合,请求每个集合并交叉结果以找到正确的结果? 我不知道。。

    谢谢!

    0 回复  |  直到 2 年前
        1
  •  1
  •   Markus sam    2 年前

    索引是加快查询速度的最重要工具之一;然而,索引应该能够保存在RAM中,因此只应创建所需的索引。这也取决于您使用的数据模型。在许多变体中创建许多索引会给集群的RAM带来很大的负载,即使您设法将其保持在最多64个索引以下。

    为了减少所需的索引数量,请查看 attribute pattern 此模式建议将属性从专用字段移动到属性数组,例如(示例取自博客文章)

    以下架构

    {
      // ...
      "releasedate_en": ISODate("2024-01-20T00:0000Z"),
      "releasedate_de": ISODate("2024-01-22T00:0000Z"),
      // ... 
     }
    

    结构如下:

    {
      // ...
      "releases": [
        { "location": "en", "date": ISODate("2024-01-20T00:0000Z") },
        { "location": "de", "date": ISODate("2024-01-22T00:0000Z") },
      ]
      // ... 
     }
    

    您可以创建一个涵盖属性名称和值的单个索引,而不是为所有属性创建专用索引,例如。

    { "releases.location": 1, "releases.date": 1}
    

    在示例中,属性具有非常同质的结构,但从技术角度来看,您也可以在数组中对具有不同值类型的属性进行分组。

    使用此模式,您可以大大减少索引的数量,并且不必描述字段的所有组合。

        2
  •  0
  •   Wernfried Domscheit    2 年前

    您不需要在低基数字段上建立索引。仅在选定字段上创建索引。例如,字段上的索引 gender 仅包含[ male , female , others ]在大多数情况下都是无用的。

    注意,并非在所有情况下都使用正常索引 $regex ,请参阅 Index Use

        3
  •  0
  •   TanThien    2 年前

    有你的问题: create every combinaison of indexes 答案是 no .有许多索引的集合使 reduced write performance and longer index builds insufficient RAM 此外,它可能会导致查询被索引误导,这不是最优的,因为索引太多。

    should I create a single compound index with all these fields ? 答案也是 。请参阅 post 创建一些索引,涵盖您需要的一些案例查询和排序。如果你有很多索引,你可以使用 hint 找出哪个选项最合适