2013-02-01 128 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