使用索引或以任何其他可能的方式在包含大型文档的大型集合中提高查询性能

2024-09-29 22:31:22 发布

您现在位置:Python中文网/ 问答频道 /正文

我将PyMongo与Flask一起使用,我想知道如何优化查询,因为我在一个包含大量文档的大型集合(8793个文档)中进行过滤

这是集合的文档结构之一:

enter image description here

如您所见,它有4个属性(simulationID、simulationPartID、timePass和status,它们存储许多数组)。此集合的大小为824.4MB。文档的平均大小为96.0KB

enter image description here

基本上,我试图找到具有simulationPartID7(1256个文档)的文档,并在其上过滤数组索引,该数组索引等于status属性中的节点ID值(作为参数接收),并获取该数组的第四个或第五个元素(取决于大小写参数),以及附加时间过程

def node_history(nodeID, case):
    coordinates = []
    node_data = db['node_data']
    db.node_data.create_index([('simulationPartID', 1), ('simulationID', 1)])
    if case == 'Temperature':
        for document in node_data.find({"simulationPartID": 7}):
            coordinates.append([document['timePass'], document['status'][int(nodeID)-1][3]])
    elif case == 'Stress':
        for document in node_data.find({"simulationPartID": 7}):
            coordinates.append([document['timePass'], document['status'][int(nodeID)-1][4]])
    else:
        pass
    coordinates.sort()
    return json.dumps(coordinates, default=json_util.default)

正如我提到的,集合非常大,根据机器的不同,执行查询大约需要30-60秒,但我希望它尽快运行,因为我希望我的应用程序尽可能具有交互性。正如您所看到的,我已经尝试在simulationIDSimulationI中创建索引onPartID属性

我以前从未使用过大型集合,因此我不喜欢索引。我甚至不知道我在代码中是否正确地使用了它。因此,我想知道是否有一种方法可以使用不同的索引方法或任何其他可能的方法优化我的查询,并使其更快

数据样本:

{
  "_id": {
    "$oid": "5f83f54d45104462898aba67"
  },
  "simulationID": "001",
  "simulationPartID": 7,
  "timePass": 0,
  "status": [
    [
      1,
      1.34022987724954e-40,
      0.00220799725502729,
      20,
      114.911392211914
    ],
    [
      2,
      0.00217749993316829,
      0.00220799725502729,
      20,
      -2.0458550453186
    ],
    [
      3,
      0.0020274999551475,
      0.00235799723304808,
      20,
      -1.33439755439758
    ],
    [
      4,
      3.36311631437956e-44,
      0.00235799723304808,
      20,
      148.233413696289
    ],
    [
      5,
      1.02169119449431e-38,
      0.000149997213156894,
      20,
      -25633.59765625
    ],
  ]
},

{  
  "_id": {
    "$oid": "5f83f54d45104462898aba68"
  },
  "simulationID": "001",
  "simulationPartID": 7,
  "timePass": 1,
  "status": [
    [
      1,
      1.34022987724954e-40,
      0.00220799725502729,
      20,
      114.911392211914
    ],
    [
      2,
      0.00217749993316829,
      0.00220799725502729,
      20,
      -2.0458550453186
    ],
    [
      3,
      0.0020274999551475,
      0.00235799723304808,
      20,
      -1.33439755439758
    ],
    [
      4,
      3.36311631437956e-44,
      0.00235799723304808,
      20,
      148.233413696289
    ],
    [
      5,
      1.02169119449431e-38,
      0.000149997213156894,
      20,
      -25633.59765625
    ],
  ]
},
{
"_id": {
    "$oid": "5f83f54d45104462898aba69"
  },
  "simulationID": "001",
  "simulationPartID": 7,
  "timePass": 2,
  "status": [
    [
      1,
      1.34022987724954e-40,
      0.00220799725502729,
      20,
      114.911392211914
    ],
    [
      2,
      0.00217749993316829,
      0.00220799725502729,
      20,
      -2.0458550453186
    ],
    [
      3,
      0.0020274999551475,
      0.00235799723304808,
      20,
      -1.33439755439758
    ],
    [
      4,
      3.36311631437956e-44,
      0.00235799723304808,
      20,
      148.233413696289
    ],
    [
      5,
      1.02169119449431e-38,
      0.000149997213156894,
      20,
      -25633.59765625
    ],
  ]
}

谢谢大家!


Tags: 方法文档idnodedata属性status数组
1条回答
网友
1楼 · 发布于 2024-09-29 22:31:22

是否为每个查询创建索引?部署应用程序时,索引只创建一次

您的find返回不需要的完整文档。您可以使用$slice限制结果

db.node_data.find({"simulationPartID": 7}, {"timePass": 1, "status": { '$slice': [ 3, 1 ] } } )

这将更快地返回数据,因为它只返回您想要得到的值

如果要从阵列中选择子元素,则可以使用此子元素:

db.collection.aggregate([
  { $match: { timePass: 2 } },
  { $set: { status: { $arrayElemAt: [ "$status", 4 ] } } },
  { $set: { status: { $arrayElemAt: [ "$status", 3 ] } } },
])

Mongo playground

相关问题 更多 >

    热门问题