MongoDb:$按$排序

Rég*_* B. 7 python sorting mongodb pymongo

我正在使用运算符运行 mongodbfind查询$in

collection.find({name: {$in: [name1, name2, ...]}})
Run Code Online (Sandbox Code Playgroud)

我希望结果按照与我的名称 array: 相同的顺序排序[name1, name2, ...]。我该如何实现这一目标?

注意:我通过 pymongo 访问 MongoDb,但我认为这并不重要。

编辑:由于不可能在 MongoDb 中本地实现这一点,所以我最终使用了典型的 Python 解决方案:

names = [name1, name2, ...]
results = list(collection.find({"name": {"$in": names}}))
results.sort(key=lambda x: names.index(x["name"]))
Run Code Online (Sandbox Code Playgroud)

Asy*_*sky 7

从即将推出的版本 3.4(2016 年 11 月)开始,您可以使用聚合框架来实现这一目标。

假设您想要的顺序是order=["David", "Charlie", "Tess"]通过此管道执行的数组:

m = { "$match" : { "name" : { "$in" : order } } };
a = { "$addFields" : { "__order" : { "$indexOfArray" : [ order, "$name" ] } } };
s = { "$sort" : { "__order" : 1 } };
db.collection.aggregate( m, a, s );
Run Code Online (Sandbox Code Playgroud)

"$addFields"阶段是 3.4 中的新增功能,它允许您"$project"在现有文档中添加新字段,而无需了解所有其他现有字段。新 "$indexOfArray"表达式返回给定数组中特定元素的位置。

此聚合的结果将是符合您的条件的文档,按照输入数组中指定的顺序排列order,并且文档将包括所有原始字段,以及一个名为__order


小智 2

不可能的。$in 运算符检查是否存在。该列表被视为已设置。

选项:

  • 拆分多个查询 name1 ... nameN 或以相同方式过滤结果。更多名称 - 更多查询。
  • 使用 itertools groupby/ifilter。在这种情况下 - 将“排序优先级”标志添加到每个文档并将 name1 与 PREC1、name2 与 PREC2 匹配,...,然后按 PREC 进行排序,然后按 PREC 进行分组。

如果您的集合在“名称”字段上有索引 - 选项 1 更好。如果没有索引或者由于写入/读取比率较高而无法创建索引 - 选项 2 适合您。