gpt4 book ai didi

mongodb - 具有两级未知父键的 Mongo 查询嵌套字段值

转载 作者:可可西里 更新时间:2023-11-01 09:28:47 27 4
gpt4 key购买 nike

我们使用 MongoDB 存储时间序列传感器数据,类似于 https://www.mongodb.com/blog/post/schema-design-for-time-series-data-in-mongodb 中所示的设计模式

我们确实在各个时间段的数据查询上取得了不错的性能。关于我们的架构设计的说明:"v"是传感器读数的父键,时间用分秒转换成嵌套数组。我们使用"m"(Minute)作为子键,然后"s"(Second)作为分钟阅读的子键。传感器读数位于 "s" 级别,field1field2、...、field10 为传感器数据值。

现在我们正在尝试实现一些数据分析工具,并希望通过传感器数据读取值来查询数据。有没有一种不在查询中使用嵌套 for 循环的情况下从数据中查询的有效方法?

例如:

  1. 具有传感器读数的项目:“field1”>2
  2. 具有传感器读数的项目:"field1">2"field3">5

感谢一百万。

记录如下例所示。

{
"_id": ObjectId("5a5dd49f74bbaefd1ac89fc8"),
"c_id": "1017",
"c_id_s": NumberInt(1017),
"c_t": NumberInt(1516096800),
"type": "hour",
"v": {
"m1": {
"s54": {
"field1": 7.373158,
"entry_id": NumberInt(4635),
"field3": 0.19,
"field2": NumberInt(88)
}
},
"m31": {
"s54": {
"field1": 5.981918,
"entry_id": NumberInt(4637),
"field3": 0.04
},
"s55": {
"field2": NumberInt(89),
"entry_id": NumberInt(4639),
"field5": NumberInt(-67)
}
}
},
"entry_id": NumberInt(4639)
},
{
"_id": ObjectId("5a5dd1a174bbaefd1ac89fc1"),
"c_id": "1024",
"c_id_s": NumberInt(1024),
"c_t": NumberInt(1516096800),
"type": "hour",
"v": {
"m3": {
"s22": {
"field3": 210.479996,
"entry_id": NumberInt(30297)
},
"s23": {
"field1": 3.271534,
"entry_id": NumberInt(30300),
"field8": 7.1875,
"field2": NumberInt(94)
}
},
"m8": {
"s23": {
"field3": 150.639999,
"entry_id": NumberInt(30304),
"field1": 2.948425,
"field8": 7.125,
"field2": NumberInt(94)
}
},
"m13": {
"s23": {
"field3": 99.799995,
"entry_id": NumberInt(30308),
"field1": 2.849621,
"field8": 7.0625,
"field2": NumberInt(95)
}
},
"m18": {
"s23": {
"field3": 59.099998,
"entry_id": NumberInt(30312),
"field1": 2.681393,
"field8": 6.9375,
"field2": NumberInt(95)
}
},
"m19": {
"s8": {
"field5": NumberInt(-87),
"entry_id": NumberInt(30313)
}
}
},
"entry_id": NumberInt(30313)
}

最佳答案

Map reduce 允许您处理命名键,但聚合是实现高效查询的方法。

您必须将数据建模为聚合框架的嵌入式文档数组。

我为您提供了两种选择。您可以针对您的数据集测试它们,看看哪一个更适合您。

有点像

"v":[
{
"minute":1,
"seconds":[
{
"second":54,
"data":{
"field1":7.373158,
"entry_id":4635,
"field3":0.19,
"field2":88
}
}
]
},
{
"minute":2,
"seconds":...
}
]

现在您可以轻松查询具有传感器读数的项目:“field1”>2。

db.col.aggregate(
[{"$match":{"v.seconds.data.field1":{"$gt":2}}},
{"$unwind":"$v"},
{"$match":{"v.seconds.data.field1":{"$gt":2}}},
{"$unwind":"$v.seconds"},
{"$match":{"v.seconds.data.field1":{"$gt":2}}},
{"$project":{"data":"$v.seconds.data"}}]
)

或者,您可以按分钟拆分文档。有点像

"v":[
{
"second":1,
"data":{
"field1":7.373158,
"entry_id":4635,
"field3":0.19,
"field2":88
}
},
{
"second":2,
"data":...
}
]

你现在可以像这样查询(在 v.data.field1 上有索引)

db.col.aggregate(
[{"$match":{"v.data.field1":{"$gt":2}}},
{"$unwind":"$v"},
{"$match":{"v.data.field1":{"$gt":2}}},
{"$project":{"data":"$v.data"}}]
)

您可以查询具有传感器读数的项目:“field1”>2 和“field3”>5

使用第一个结构

db.col.aggregate(
[{"$match":{"v":{"$elemMatch":{"seconds": {$elemMatch:{"field1":{$gt":2},"field3":{$gt":5}}}}}}},
{"$unwind":"$v"},
{"$match":{"v.seconds": {$elemMatch:{"field1":{$gt":2},"field3":{$gt":5}}}}},
{"$unwind":"$v.seconds"},
{"$project":{"data":"$v.seconds.data"}}]
)

使用第二种结构

db.col.aggregate(
[{"$match":{"v.data":{$elemMatch:{"field1":{$gt":2},"field3":{$gt":5}}}}},
{"$unwind":"$v"},
{"$match":{"v.data.field1":{"$gt":2},"v.data.field3":{"$gt":5} }},
{"$project":{"data":"$v.data"}}]
)

Mongo 更新 3.6

$match$expr 接受聚合表达式。

$gt > 0 - 聚合表达式,用于检查一分钟内所有匹配秒标准的总和是否大于 0

$objectToArray 将命名键转换为键值对,后跟输入条件的 $filter 秒,并输出匹配秒记录的编号。

db.testcol.aggregate(
{"$match":{
"$expr":{
"$gt":[
{"$sum":{
"$map":{
"input":{"$objectToArray":"$v"},
"as":"secondsofminute",
"in":{
"$size":{
"$filter":{
"input":{"$objectToArray":"$$secondsofminute.v"},
"as":"seconds",
"cond":{"$gt":["$$seconds.v.field2",2]}
}
}
}
}
}},
0]
}
}})

Mongo 更新 3.4 - 将 $expr 替换为 $redact

db.col.aggregate(
{"$redact":{
"$cond":{
"if":{
"$gt":[
{"$sum":{
"$map":{
"input":{"$objectToArray":"$v"},
"as":"secondsofminute",
"in":{
"$size":{
"$filter":{
"input":{"$objectToArray":"$$secondsofminute.v"},
"as":"seconds",
"cond":{"$gt":["$$seconds.v.field2",2]}
}
}
}
}
}},
0]
},
"then":"$$KEEP",
"else":"$$PRUNE"
}
}})

关于mongodb - 具有两级未知父键的 Mongo 查询嵌套字段值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48279637/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com