繁体   English   中英

MongoDb: $sort by $in

[英]MongoDb: $sort by $in

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

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"]))

您可以使用从即将发布的 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的附加字段

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

选项:

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

如果您的收藏在“名称”字段上有索引 - 选项 1 更好。 如果没有索引或者由于写入/读取比率高而无法创建索引 - 选项 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 上测试

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM