Support for sorting.

This commit is contained in:
Jim Menard 2008-12-09 15:06:35 -05:00
parent f961339cf5
commit 89d8076d11
3 changed files with 45 additions and 9 deletions

2
README
View File

@ -57,8 +57,6 @@ type
* Capped collection support.
* Implement order_by (right now, sort order is ignored)
* More code comments. More text in this file.
* Support more types: REF, SYMBOL, CODE_W_SCOPE, etc.

View File

@ -1,5 +1,6 @@
require 'mongo/message/message'
require 'mongo/message/opcodes'
require 'mongo/util/ordered_hash'
module XGen
module Mongo
@ -13,7 +14,30 @@ module XGen
write_string("#{db_name}.#{collection_name}")
write_int(query.number_to_skip)
write_int(query.number_to_return)
write_doc(query.selector)
sel = query.selector
if query.order_by
sel = OrderedHash.new
sel['query'] = query.selector
sel['orderby'] = case query.order_by
when Array
if query.order_by.empty? # Empty array of order_by values
[]
else
case query.order_by[0]
when Hash # Array of hashes
query.order_by
else # ['a', 'b']
query.order_by.collect { |v| {v => 1} } # Assume ascending order for all values
end
end
when Hash # Should be an ordered hash, but this message doesn't care
a = []
query.order_by.each { |k,v| a << {k => v }}
a
end
end
write_doc(sel)
write_doc(query.fields) if query.fields
end

View File

@ -107,16 +107,30 @@ class DBAPITest < Test::Unit::TestCase
@coll.insert('b' => 3)
# Sorting (ascending)
order_by = OrderedHash.new
order_by['a'] = 1
docs = @coll.find({'a' => { '$lt' => 10 }}, :sort => order_by).map
docs = @coll.find({'a' => { '$lt' => 10 }}, :sort => [{'a' => 1}]).map
assert_equal 2, docs.size
assert_equal 1, docs.first['a']
# Sorting (descending)
order_by = OrderedHash.new
order_by['a'] = -1
docs = @coll.find({'a' => { '$lt' => 10 }}, :sort => order_by).map
docs = @coll.find({'a' => { '$lt' => 10 }}, :sort => [{'a' => -1}]).map
assert_equal 2, docs.size
assert_equal 2, docs.first['a']
# Sorting using array of names; assumes ascending order
# NOTE: Mongo itself does not yet properly sort by multiple names
docs = @coll.find({'a' => { '$lt' => 10 }}, :sort => ['a']).map
assert_equal 2, docs.size
assert_equal 1, docs.first['a']
# Sorting using empty array; no order guarantee but should not blow up.
docs = @coll.find({'a' => { '$lt' => 10 }}, :sort => [{'a' => -1}]).map
assert_equal 2, docs.size
# Sorting using ordered hash. You can use an unordered one, but then the
# order of the keys won't be guaranteed thus your sort won't make sense.
oh = OrderedHash.new
oh['a'] = -1
docs = @coll.find({'a' => { '$lt' => 10 }}, :sort => oh).map
assert_equal 2, docs.size
assert_equal 2, docs.first['a']
end