5

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

collection.find({name: {$in: [name1, name2, ...]}})

我希望结果按与我的名称数组相同的顺序排序:[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"]))
4

3 回答 3

5

您可以使用从即将发布的 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 );

"$addFields"阶段是 3.4 中的新阶段,它允许您在"$project"不知道所有其他现有字段的情况下为现有文档添加新字段。新 "$indexOfArray"表达式返回给定数组中特定元素的位置。

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

于 2016-10-24T20:04:13.680 回答
2

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

选项:

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

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

于 2013-02-04T11:11:11.513 回答
2

Vitaly 是正确的,使用 find 无法做到这一点,但可以使用聚合来实现:

db.collection.aggregate( [ { $match: { name: {$in: [name1, name2, ...]} }, { $project: { 'name': 1, 'name1': { $eq: [ 'name1', '$name' ] }, 'name2': { $eq: [ 'name2', '$name' ] } } }, { $sort: { 'name1': 1, 'name2': 1 } } ] )

在 2.6.5 上测试

我希望这会向其他人暗示正确的方向。

于 2014-12-22T01:52:18.290 回答