nosql - mongoDB的排序问题
大家讲道理
大家讲道理 2017-04-21 10:56:29
0
4
708

有一个List ArrayList<Long> al=new ArrayList<Long>();里面存储了从外部获取的数据的ID并且进行了排序(随机抽取的ID,按照先后放入LIST),然后把这些ID在mongoDB通过inObj.put("_id", new BasicDBObject("$in", list));进行in查询,获取后的结果并不和LIST中ID的顺序一样,搜索了一下,有文章说不指定排序的话,mongodb会按照$natural进行排序,但是我测试了一下,并不是这样。
现在问题是怎么才能让mongodb按照list的排序获取结果呢

大家讲道理
大家讲道理

光阴似箭催人老,日月如移越少年。

全部回覆(4)
伊谢尔伦

這是個很好的問題。其實你查的文章沒有說錯,不指定排序,就是依照自然排序來排的。只不過這個自然排序是指按照_id的自然排序去排。你的list只是一个查询条件,就相当于x > max AND x < min指定的一个查询范围,跟排序完全没有关系,不论是什么数据库系统,都会在你指定的这个list範圍內找到資料後再按自身的排序方法來排序。

我的建議是你還是照這種方法去取值,取出後,自己在java程式裡循環一遍,然後跑出排序後的陣列。

伊谢尔伦

@joyqi 的說法不太對,MongoDB裡的自然排序(也就是按$natural字段排序)與按_id字段排序是不同的。自然排序是按資料在資料檔案中的組織順序來排序的。

你可以explain一下你的查詢,就能看到它利用索引的情況,例如你用下面的語句插入資料:

> db.test.insert({a:2,b:1})
> db.test.insert({a:1,b:2})
> db.test.insert({a:2,b:3})
> db.test.insert({a:1,b:4})

在你不對a欄位加索引時,會得到下面的結果,以下是自然排序的結果:

> db.test.find({a:{$in:[1,2]}})
{ "_id" : ObjectId("4f509380ea72116cb2137567"), "a" : 2, "b" : 1 }
{ "_id" : ObjectId("4f509380ea72116cb2137568"), "a" : 1, "b" : 2 }
{ "_id" : ObjectId("4f509380ea72116cb2137569"), "a" : 2, "b" : 3 }
{ "_id" : ObjectId("4f509380ea72116cb213756a"), "a" : 1, "b" : 4 }

因為這時候MongoDB是排表的查詢,掃到一條資料滿足條件就加入回傳清單。所以是按自然順序來做的。

而如果你加上索引再查,會得到下面的結果

> db.test.ensureIndex({a:1})
> db.test.find({a:{$in:[1,2]}})
{ "_id" : ObjectId("4f509537ea72116cb213756f"), "a" : 1, "b" : 4 }
{ "_id" : ObjectId("4f509530ea72116cb213756d"), "a" : 1, "b" : 2 }
{ "_id" : ObjectId("4f509534ea72116cb213756e"), "a" : 2, "b" : 3 }
{ "_id" : ObjectId("4f50952cea72116cb213756c"), "a" : 2, "b" : 1 }

可以看到,結果按a為1,a為2分開了,因為按索引查詢時,相當於是在索引中查多段數據,這裡的例子裡,相當於是查了a的範圍為[1,1]和[2,2]兩個範圍的數據,這兩次在邏輯上是串列的,先查[1,1]的數據,再查[2,2]的數據,所以這裡a為1和2的分開了。

伊谢尔伦

沒用過mongodb,不過感覺這個問題的答案和別的關係型資料庫一樣的。如果你在關係型資料庫中這樣插入ID,而ID又是主鍵的話,那麼資料庫會自動按照ID的值進行排序,因為主鍵本身就是一個聚集索引,要達到你想要的效果很簡單,不要自己生成ID,讓Mongodb產生一個自動自增的ID,這樣插入時排序是按照這個自增值排序的,你讀取的時候也是按照插入順序讀取的。

左手右手慢动作

搜出來再排!

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!