首页 新闻 赞助 找找看

C# MongoDB 查询优化

0
悬赏园豆:100 [已解决问题] 解决于 2021-04-22 16:47

先举个例子,我用MongoDB 存储天气数据,格式大概是下面的样子:

[{
        "_id": "ObjectId(\"5fcdf576b65c60d7fd7f2626\")",
        "Station": "1234567890",
        "DataTime": "2021-04-20 09:27:00",
        "Datas": [{
            "Factor": "Temperature",
            "Value": 20.3,
            "Unit": ""
        }, {
            "Factor": "Temperature",
            "Value": 50.3,
            "Unit": ""
        }, {
            "Factor": "Humidity",
            "Value": 1,
            "Unit": "%"
        }]
    },
    {
        "_id": "ObjectId(\"5fcdf576b65c60d7fd7f2626\")",
        "Station": "1234567891",
        "DataTime": "2021-04-20 09:27:00",
        "Datas": [{
            "Factor": "Temperature",
            "Value": 20.3,
            "Unit": ""
        }, {
            "Factor": "湿度",
            "Value": 1,
            "Unit": "%"
        }]
    }
]

数据每个Station每分钟1条,500个station,其中Datas是个数组(里面大概有100个以上的对象),因为有的station采集的因子数量不同,所以,就做成了数组嵌套了起来,跑了一个多月,查询起来很慢。尤其是查询这这500个station的1小时内的数据,用于计算平均值就更慢的离谱了,光查询就得有5,6分钟的样子,求大佬指教。

查询代码如下:

var list = collection.Find(x => x.DataTime <= DateTime.Parse("2021-03-29 17:59:00") && x.DataTime >= DateTime.Parse("2021-03-29 17:00:00"))
                .Project(c => new RealTimeData { Id = c.Id, DataTime = c.DataTime, Station = c.Station, Datas = c.Datas.Where(x => x.Factor.Equals("Temperature")) }).ToList();

并且试过用ElemMatch去过滤嵌套子集合也不好使,查询出来的子集时全部:

FilterDefinitionBuilder<RealTimeData> builder = Builders<RealTimeData>.Filter;
            var filter =builder.Lte(x => x.DataTime, DateTime.Parse("2021-03-29 17:59:00"))
                & builder.Gte(x => x.DataTime, DateTime.Parse("2021-03-29 17:00:00"))
                & builder.ElemMatch(x => x.Datas, y => y.Factor.Equals("Temperature"));
            var list1 = collection.Find(filter).ToList();

上面代码都是经过脱敏处理的,但是大概样子是这样,求高人指点。

Yu2的主页 Yu2 | 初学一级 | 园豆:102
提问于:2021-04-20 20:24
< >
分享
最佳答案
0

1.datetime 字段 加个索引,先试试看
2.datas 数据有点大,量不可控。考虑拆分出去。先查station,处理业务时 再查 factor

收获园豆:50
gt1987 | 小虾三级 |园豆:1150 | 2021-04-21 10:05

是有索引的,共两个索引,{datatime -1,Datas.Factor 1}另一个是{station 1,datatime -1,Datas.Factor 1},目前最快的方式是用游标去查询,并且里面也用project选择查询部分字段,这样最快的情况下,查询结果3W条,里面datas中大概20多条,耗时50秒。

Yu2 | 园豆:102 (初学一级) | 2021-04-21 10:12
其他回答(1)
0

设计有问题,把datas分开,单独存到一个document,带上一个station的id

收获园豆:50
不知道风往哪儿吹 | 园豆:2035 (老鸟四级) | 2021-04-22 13:41

现在是这么尝试的,但是似乎没啥效果,查询一小时时的数据,上面取出了3w条,datas要取3w*12条,主子集合取完,大概耗时100秒左右。

支持(0) 反对(0) Yu2 | 园豆:102 (初学一级) | 2021-04-22 16:12

@Yu2: 其实查询速度挺快的,慢就慢在最后面那个tolist,你可以打个断点调试一下

支持(0) 反对(0) 不知道风往哪儿吹 | 园豆:2035 (老鸟四级) | 2021-04-22 16:33

@不知道风往哪儿吹: 是这样,取数据的过程很慢,而且也很耗内存,这就有点坑了。

支持(0) 反对(0) Yu2 | 园豆:102 (初学一级) | 2021-04-22 16:38

@Yu2: 你把这么多数据放到内存,肯定慢,你先把要处理的数据都处理好,然后得到你需要的数据再放到内存,总之就是不要把查询的数据一下全放到内存

支持(0) 反对(0) 不知道风往哪儿吹 | 园豆:2035 (老鸟四级) | 2021-04-22 16:45
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册