前阵子同事有一个需求: 在一个数组嵌套map的结构中,首先按照map中的某个key进行筛选,再按照map中的某个key进行排序,但是奇怪的是数据总是乱序的。
再检查了代码和数据之后并没有发现什么错误,于是自己进行了简单的demo测试,结果基本相同的代码和数据竟然是有序的。
demo如下:
from pymongo import MongoClient from random import randint db = MongoClient(‘mongodb://mongodb_temp‘)[‘mydatabase‘].mycollection for i in range(20): db.insert_one( { "host": "host1", "type": "type1", "data": [ { "t": 10000, "v": randint(0, 100) }, { "t": 10001, "v": randint(0, 100) }, ] }) my_filter = {‘host‘: ‘host1‘, ‘type‘: ‘type1‘, ‘data‘: {‘$elemMatch‘: {‘t‘: 10000}}} projection = {‘host‘: 1, ‘type‘: 1, ‘data‘: {‘$elemMatch‘: {‘t‘: 10000}}} sort_key = ‘data.0.v‘ rs = db.find(my_filter, projection).sort(sort_key, 1) rs = list(rs) for v in rs: print(v["data"][0][‘v‘])
最后竟然发现原来是数据顺序导致的问题,更改数据顺序如下 就会复现问题:
for i in range(20): data_0, data_1 = {"t": 10000, "v": random.randint(0, 100)}, {"t": 10001, "v": random.randint(0, 100)} insert_d = { "host": "host1", "type": "type1", "data": [data_0, data_1] if i != 10 else [data_1, data_0] } db.insert_one(insert_d)
暂时不清楚内部的实现原理,附上我在Stack Overflow的提问: https://*.com/questions/65405113/pymongo-use-sort-with-elemmatch-doesnt-work