Swift中RealmSwift的$sort阶段如何确保BSON文档键值对顺序?
问题
在Swift中使用RealmSwift包执行MongoDB聚合查询时,遇到$sort阶段排序逻辑不稳定的问题:
执行聚合查询的代码:
db.collection(withName: "Example").aggregate(pipeline: aggregatePipeline) { ... }
定义的聚合管道:
let aggregatePipeline: [Document] = [ [ "$sort": [ "seen": 1 , "score": -1, "_id": -1 ] ] ]
每次运行查询时,排序结果的字段优先级随机变化:有时按预期优先按seen排序,有时却先按_id或score排序。打印聚合阶段后发现,BSON文档内的键值对顺序每次都不固定:
首次运行输出:
["$sort": Optional(RealmSwift.AnyBSON.document(["_id": Optional(RealmSwift.AnyBSON.int64(-1)), "seen": Optional(RealmSwift.AnyBSON.int64(1)), "score": Optional(RealmSwift.AnyBSON.int64(-1))]))]
第二次运行输出:
["$sort": Optional(RealmSwift.AnyBSON.document(["seen": Optional(RealmSwift.AnyBSON.int64(1)), "score": Optional(RealmSwift.AnyBSON.int64(-1)), "_id": Optional(RealmSwift.AnyBSON.int64(-1))]))]
需要解决的问题:如何编写具有确定键值对顺序的BSON文档,以传递给$sort阶段,保证排序逻辑的稳定性?
解决方案
问题根源是Swift的普通字典[String: Any]是无序的,每次初始化或序列化时键的顺序会随机变化,而MongoDB的$sort阶段对字段顺序有严格要求——排序优先级由字段在文档中的顺序决定。
要生成有序的BSON文档,需要使用RealmSwift提供的有序文档构造方式,具体有两种实现方式:
方式1:使用Document的有序初始化方法
直接通过Document的有序键值对数组来初始化,确保字段顺序固定:
let sortDoc = Document([ ("seen", 1), ("score", -1), ("_id", -1) ]) let aggregatePipeline: [Document] = [ ["$sort": sortDoc] ]
方式2:使用AnyBSON.document的有序构造器
如果需要直接构造AnyBSON类型的有序文档,可以用键值对数组作为参数:
let aggregatePipeline: [Document] = [ [ "$sort": AnyBSON.document([ ("seen", .int64(1)), ("score", .int64(-1)), ("_id", .int64(-1)) ]) ] ]
两种方式都能确保$sort阶段的字段顺序严格按照你定义的优先级执行,避免排序逻辑随机变化的问题。
内容的提问来源于stack exchange,提问作者ambassador
相关产品推荐
相关产品推荐

