对深度嵌套对象的查询,将嵌套对象中的每个键与mongodb匹配

时间:2019-08-15 15:03:04

标签: database mongodb nosql

我有一个非常不寻常的结构,看起来像这样(实际上更多地嵌套在现实中):

{
  "2019-12-05": {
    "10": {
      "us": {
        "6631_10_s902381": {
          revenue: 30,
          approved: 14,
          clicks: 20,
          hosts: 10
        }
      },
      "fr": {
        "6631_10_s902381": {
          revenue: 60,
          approved: 4,
          clicks: 2,
          hosts: 1
        },
        "2631_11_s902381": {
          revenue: 20,
          approved: 7,
          clicks: 3,
          hosts: 0
        }
      }
    },
    "14": {
      "us": {
        "5630_12_9502345": {
          revenue: 20,
          approved: 4,
          clicks: 0,
          hosts: 0          
        }
      }
    }
  },
  "2019-12-06": ...
}

最初,我考虑过使用mysql进行这种结构设计,但是会重复很多,因为最深的对象包含特定于其上方所有参数的数据(数据)。

如果我在Mysql上执行此操作,则将如下所示:

date          hour          country         sub                       revenue   approved    clicks  hosts
2019-12-05    10            us              "6631_10_s902381"         30        14          20      10
2019-12-05    10            fr              "6631_10_s902381"         60        4           2       1
2019-12-05    10            fr              "2631_11_s902381"         20        7           3       0
2019-12-05    14            us              "5630_12_9502345"         20        4           0       0
2019-12-06    ...

我必须在所有字段的组合上创建唯一/主索引,直到“收入”为止。如您所见,会有很多重叠。

但是,我将需要查询数据库内容,例如“获取日期== 2019-12-05和国家/地区==我们的所有数据(因此忽略小时和子参数)”,我不会我不知道如何使用mongodb实现这一目标。 我尝试过:

db.reports.find({"2019-12-05.$.us": { $exists: true}})

但这没用。

我的问题是:

  1. 您对我的需求有更好的数据库或架构的建议吗?
  2. 是否可以让我的查询在mongodb中工作?当我尝试套用2级嵌套的键时,可以匹配对象中的每个键吗?

1 个答案:

答案 0 :(得分:0)

您不能在非数组中为mongodb使用标识符$$[identifier]。我建议像这样的架构重组:

{
  {
    "date": ISODate(date)
    "us": [
      "10": {...},
      "14": {...}
    ],
  },
  {
    "date": ISODate(date)
    "fr": [
      "10": {...},
      "14": {...}
    ],
  }
}

请注意,我将日期更改为ISODate,以便Mongo可以在需要时更轻松地查询日期或日期范围。另请注意,我不知道数字10和14在您的数据集中的重要性,因此我不知道此结构是否完全适合您。

但是,有了这个新的数据结构,您现在可以运行如下查询:

db.collection.find({"us": {$exists: true}, date: {$gte: new Date(date at midnight)}, {$lte: new Date(date at 11:59:59pm)  })