In
http://clojuremongodb.info/articles/querying.html, there's this example:
;; find top 10 scores that will be returned as Clojure maps
(with-collection "scores"
(find {})
(fields [:score :name])
;; it is VERY IMPORTANT to use sorted maps with sort
(sort (sorted-map :score -1 :name 1))
(limit 10))
Is that advice about sorted-map right? It seems like it should be an array-map (relying on the [undocumented?] feature that array-maps are in key order). For example:
I have this compound index:
{
"v" : 1,
"key" : {
"user" : NumberLong(1),
"timestamp" : NumberLong(1)
},
"ns" : "student.student_records",
"name" : "user_1_timestamp_1"
}
It was created like this (per "Creating indexes" in
http://clojuremongodb.info/articles/collections.html):
(mc/ensure-index collection (array-map :user 1, :timestamp 1))
I populated the collection like this:
(mc/insert ps/collection {:_id 6, :user 111, :timestamp (DateTime. 343)})
(mc/insert ps/collection {:_id 4, :user 11, :timestamp (DateTime. 10000)})
(mc/insert ps/collection {:_id 2, :user 11, :timestamp (DateTime. 100)})
(mc/insert ps/collection {:_id 3, :user 11, :timestamp (DateTime. 1000)})
(mc/insert ps/collection {:_id 5, :user 111, :timestamp (DateTime. 10)})
(mc/insert ps/collection {:_id 1, :user 1, :timestamp (DateTime. 1)})
The expected order after a sort should be ascending order by ids. I get that expected order from these three queries:
(with-collection collection (find {}) (sort (sorted-map :user 1)))
;; including these two from the Mongo shell
> db.student_records_test.find().sort({user: 1})
> db.student_records_test.find().sort({user: 1, timestamp: 1})
However, this doesn't work:
(with-collection collection (find {}) (sort (sorted-map :user 1, :timestamp 1)))
It's in timestamp order:
:user 1, :timestamp (DateTime. 1
:user 111, :timestamp (DateTime. 10)
:user 11, :timestamp (DateTime. 100
:user 111, :timestamp (DateTime. 343
:user 11, :timestamp (DateTime. 1000)})
:user 11, :timestamp (DateTime. 10000)})
That's what I'd expect because the :timestamp will be sorted before the :user.
If I use an array-map, things work as I'd expect:
(map :_id (with-collection collection (find {}) (sort (array-map :user 1, :timestamp 1))))
(1 2 3 4 5 6)
---
O wad some Pow'r the giftie gie us
To see oursels as ithers see us!
-- Bobbie Burns