首页 > 解决方案 > 用于按对象键搜索的结构嵌套对象列表

问题描述

我有从收集点 ( sourceId) 获取的数据,收集点 ( ) 记录samples来自不同探头 ( ) 的数据 ( probeId)。我需要按 bysamples构造数据。probeIdsourceId

规格

  1. 经常插入
  2. 偶尔阅读
  3. 从不更新或删除
  4. sourceIds通过使用列表和列表进行索引来读取probeIds
  5. 原子插入,包括何时probeId不在探针列表中且需要创建探针子文档

问题

实现上述目标的最佳结构是什么?特别是,首选结构如何有助于实现第 5 点?我无法让 upsert 仅匹配probeId并忽略samplesand meta

到目前为止,我已经考虑了以下两种结构:

{'sourceId': ObjectId(),
  'probes': [
    {
      'probeId': ObjectId(),
      'meta': {...},
      'samples': [...]
    },
    ...
  ]
}

{'sourceId': ObjectId(),
  'probes': [
    {
      ObjectId(): {                # probeId key
        'meta': {...},
        'samples': [...]
      }
    }
  ]
}

目前我使用第一个结构并像这样搜索:

  db.collection.aggregate(
    {'$match': {'sourceId': {'$in': source_id_list}}},
    {'$project': {'probes': {'$filter': {'input': '$probes', 'cond': {'$in': ['$$this.probeId', probe_id_list]}}}}}
  )

为清楚起见,第 5 点应按如下方式工作(假设使用第一个结构):

插入前:

{'sourceId': ObjectId('1'),
  'probes': [
    {
      'probeId': ObjectId('2'),
      'meta': {...},
      'samples': [...]
    }
  ]
}

probeId在为=3插入一个示例之后,对于sourceId=1(请注意,不仅添加了示例,还添加了包含子文档):

{'sourceId': ObjectId('1'),
  'probes': [
    {
      'probeId': ObjectId('2'),
      'meta': {...},
      'samples': [...]
    },
    {
      'probeId': ObjectId('3'),
      'meta': {},
      'samples': [<NEW SAMPLE DATA>]
    }
  ]
}

标签: mongodbmongodb-query

解决方案


推荐阅读