搜尋

首頁  >  問答  >  主體

nosql - mongoDB的排序問題

有一個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的排序獲取結果呢

大家讲道理大家讲道理2802 天前762

全部回覆(4)我來回復

  • 伊谢尔伦

    伊谢尔伦2017-04-21 10:58:29

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

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

    回覆
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-21 10:58:29

    @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的分開了。

    回覆
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-21 10:58:29

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

    回覆
    0
  • ringa_lee

    ringa_lee2017-04-21 10:58:29

    搜出來再排!

    回覆
    0
  • 取消回覆