【问题标题】:MongoDB Index Strategy For Many Query Possibilities用于许多查询可能性的 MongoDB 索引策略
【发布时间】:2023-02-02 11:06:46
【问题描述】:

我有一个包含一些数据的 MongoDB 集合。我简化了下面的示例,但假设每个对象都有 10 个键,它们的数据类型是数字、日期和数字数组以及子文档的混合体。

{
    '_id': ObjectId,
    A: number,
    B: number,
    C: datetime,
    D: [
        number, number, number
    ]
}

我有一个应用程序可以针对任意组合的键 A、B、C 和 D 发送查询,例如 {A: 1, C: 'ABC' } 和 { B: 10: D: 2 }。除了几个字段之外,每个查询都应该具有足够的性能以在 5 秒内返回。

我知道 MongoDB 复合索引仅在查询键顺序与索引的顺序匹配时使用。因此,即使在每个键 { A: 1, B: 1, C: 1, D: 1 } 上建立索引,对 { A: 2, D: 1 ] 的查询也不会使用该索引。因此,我最好的选择是为每个键组合制作索引吗?考虑到每个文档上的键数,这似乎相当困难,但不确定我还能如何解决这个问题?我考虑过让所有查询查询每个键,以便顺序始终相同,但不确定在未查询特定键时如何编写查询。例如,应用程序想要查询 B 的某个值,但也需要

{
    A: SomeAllMatchingValue?,
    B: 1:,
    C: SomeAllMatchingValue?,
    D: SomeAllMatchingValue? 
}

我想知道将最少查询的字段保留在查询的最后是否有意义,因为索引前缀适用于大多数普通用例,但减少了需要生成的索引数量。

对于这个用例,推荐的最佳实践是什么?谢谢!

编辑:

经过进一步研究,我认为属性模式是可行的方法。数字文档键可以全部移动到属性中,并且一个索引可以覆盖所有基础。

https://www.mongodb.com/blog/post/building-with-patterns-the-attribute-pattern

【问题讨论】:

    标签: mongodb mongodb-query mongodb-.net-driver


    【解决方案1】:

    您的案例似乎是 wildcard index 的完美用例, 这是在 MongoDB v4.2+ 中引入的。

    您可以像这样创建所有顶级字段的通配符索引:

    db.collection.createIndex( { "$**" : 1 } )
    

    以任意标准运行:

    {
      D: 3,
      B: 2,
    }
    

    或者

    {
      A: 1,
      C: ISODate('1970-01-01T00:00:00.000+00:00')
    }
    

    将在 explain() 中产生 IXSCAN

    {
      "explainVersion": "1",
      "queryPlanner": {
        ...
        "parsedQuery": {
          "$and": [
            ...
          ]
        },
        ...
        "winningPlan": {
          "stage": "FETCH",
          "filter": {
            "C": {
              "$eq": {
                "$date": {
                  "$numberLong": "0"
                }
              }
            }
          },
          "inputStage": {
            "stage": "IXSCAN",
            "keyPattern": {
              "$_path": 1,
              "A": 1
            },
            "indexName": "$**_1",
            ...
            "indexBounds": {
              ...
            }
          }
        },
        "rejectedPlans": [
          ...
        ]
      },
      ...
    }
    

    【讨论】:

      猜你喜欢
      • 2013-07-25
      • 1970-01-01
      • 2015-10-24
      • 1970-01-01
      • 2023-03-23
      • 2021-02-07
      • 1970-01-01
      • 1970-01-01
      • 2013-03-15
      相关资源
      最近更新 更多