2013-02-01 130 views
3

排序我正在运行的MongoDB find查询与$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"])) 
+0

你的意思是你想记录首先包含name1,后面是包含name2的记录? – paulmelnikow

+0

是的,确切地说。在目前的情况下,名字是独一无二的,但这并不相关,是吗? –

+0

目前不能通过正常查询 – Sammaye

回答

2

不可能。 $ in操作员检查存在。该列表被视为已设置。

选项:

  • 拆分为若干查询的姓名1 ... nameN或过滤的结果一样。 更多名称 - 更多查询。
  • 使用itertools groupby/ifilter。在这种情况下 - 将“排序优先权”标志添加到每个文档,并将name1与PREC1,name2与PREC2,....匹配,然后由PREC分类,然后由PREC分组。

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

1

维塔利是正确的,这是不可能做到这一点与找到,但它可以与骨料来实现:

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

我希望这将暗示其他人的权利方向。

1

您可以从即将推出的版本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