Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Merge pull request #170 from estolfo/index_tests

RUBY-564 Support for (hashed, text, 2dsphere) index types
  • Loading branch information...
commit 6b803219b2f65c3db142d6195adc3bbc03652c8e 2 parents 6428bf6 + 26b7ddc
Emily estolfo authored
11 lib/mongo.rb
@@ -2,7 +2,18 @@ module Mongo
2 2 ASCENDING = 1
3 3 DESCENDING = -1
4 4 GEO2D = '2d'
  5 + GEO2DSPHERE = '2dsphere'
5 6 GEOHAYSTACK = 'geoHaystack'
  7 + TEXT = 'text'
  8 + HASHED = 'hashed'
  9 + INDEX_TYPES = [ ASCENDING,
  10 + DESCENDING,
  11 + GEO2D,
  12 + GEO2DSPHERE,
  13 + GEOHAYSTACK,
  14 + TEXT,
  15 + HASHED
  16 + ]
6 17
7 18 DEFAULT_MAX_BSON_SIZE = 4 * 1024 * 1024
8 19 DEFAULT_MAX_MESSAGE_SIZE = DEFAULT_MAX_BSON_SIZE * 2
39 lib/mongo/collection.rb
@@ -483,8 +483,9 @@ def update(selector, document, opts={})
483 483 #
484 484 # @param [String, Array] spec
485 485 # should be either a single field name or an array of
486   - # [field name, direction] pairs. Directions should be specified
487   - # as Mongo::ASCENDING, Mongo::DESCENDING, or Mongo::GEO2D.
  486 + # [field name, type] pairs. Index types should be specified
  487 + # as Mongo::ASCENDING, Mongo::DESCENDING, Mongo::GEO2D, Mongo::GEO2DSPHERE, Mongo::GEOHAYSTACK,
  488 + # Mongo::TEXT or Mongo::HASHED.
488 489 #
489 490 # Note that geospatial indexing only works with versions of MongoDB >= 1.3.3+. Keep in mind, too,
490 491 # that in order to geo-index a given field, that field must reference either an array or a sub-object
@@ -501,6 +502,8 @@ def update(selector, document, opts={})
501 502 # feature is only available in MongoDB >= 1.3.2.
502 503 # @option opts [Boolean] :drop_dups (nil) If creating a unique index on a collection with pre-existing records,
503 504 # this option will keep the first document the database indexes and drop all subsequent with duplicate values.
  505 + # @option opts [Integer] :bucket_size (nil) For use with geoHaystack indexes. Number of documents to group
  506 + # together within a certain proximity to a given longitude and latitude.
504 507 # @option opts [Integer] :min (nil) specify the minimum longitude and latitude for a geo index.
505 508 # @option opts [Integer] :max (nil) specify the maximum longitude and latitude for a geo index.
506 509 #
@@ -525,11 +528,12 @@ def update(selector, document, opts={})
525 528 #
526 529 # @core indexes create_index-instance_method
527 530 def create_index(spec, opts={})
528   - opts[:dropDups] = opts[:drop_dups] if opts[:drop_dups]
529   - field_spec = parse_index_spec(spec)
530   - opts = opts.dup
531   - name = opts.delete(:name) || generate_index_name(field_spec)
532   - name = name.to_s if name
  531 + opts[:dropDups] = opts[:drop_dups] if opts[:drop_dups]
  532 + opts[:bucketSize] = opts[:bucket_size] if opts[:bucket_size]
  533 + field_spec = parse_index_spec(spec)
  534 + opts = opts.dup
  535 + name = opts.delete(:name) || generate_index_name(field_spec)
  536 + name = name.to_s if name
533 537 generate_indexes(field_spec, name, opts)
534 538 name
535 539 end
@@ -551,11 +555,12 @@ def create_index(spec, opts={})
551 555 #
552 556 # @return [String] the name of the index.
553 557 def ensure_index(spec, opts={})
554   - now = Time.now.utc.to_i
555   - opts[:dropDups] = opts[:drop_dups] if opts[:drop_dups]
556   - field_spec = parse_index_spec(spec)
557   - name = opts[:name] || generate_index_name(field_spec)
558   - name = name.to_s if name
  558 + now = Time.now.utc.to_i
  559 + opts[:dropDups] = opts[:drop_dups] if opts[:drop_dups]
  560 + opts[:bucketSize] = opts[:bucket_size] if opts[:bucket_size]
  561 + field_spec = parse_index_spec(spec)
  562 + name = opts[:name] || generate_index_name(field_spec)
  563 + name = name.to_s if name
559 564
560 565 if !@cache[name] || @cache[name] <= now
561 566 generate_indexes(field_spec, name, opts)
@@ -1017,11 +1022,13 @@ def parse_index_spec(spec)
1017 1022 end
1018 1023 elsif spec.is_a?(Array) && spec.all? {|field| field.is_a?(Array) }
1019 1024 spec.each do |f|
1020   - if [Mongo::ASCENDING, Mongo::DESCENDING, Mongo::GEO2D, Mongo::GEOHAYSTACK].include?(f[1])
  1025 + if Mongo::INDEX_TYPES.include?(f[1])
1021 1026 field_spec[f[0].to_s] = f[1]
1022 1027 else
1023 1028 raise MongoArgumentError, "Invalid index field #{f[1].inspect}; " +
1024   - "should be one of Mongo::ASCENDING (1), Mongo::DESCENDING (-1) or Mongo::GEO2D ('2d')."
  1029 + "should be one of Mongo::ASCENDING (#{Mongo::ASCENDING}), Mongo::DESCENDING (#{Mongo::DESCENDING}), " +
  1030 + "Mongo::GEOHAYSTACK ('#{Mongo::GEOHAYSTACK}'), Mongo::GEO2DSPHERE ('#{Mongo::GEO2DSPHERE}'), " +
  1031 + "Mongo::TEXT ('#{Mongo::TEXT}'), or Mongo::HASHED ('#{Mongo::HASHED}')"
1025 1032 end
1026 1033 end
1027 1034 else
@@ -1109,8 +1116,8 @@ def insert_documents(documents, collection_name=@name, check_keys=true, write_co
1109 1116
1110 1117 def generate_index_name(spec)
1111 1118 indexes = []
1112   - spec.each_pair do |field, direction|
1113   - indexes.push("#{field}_#{direction}")
  1119 + spec.each_pair do |field, type|
  1120 + indexes.push("#{field}_#{type}")
1114 1121 end
1115 1122 indexes.join("_")
1116 1123 end
2  lib/mongo/db.rb
@@ -441,7 +441,7 @@ def drop_index(collection_name, index_name)
441 441 #
442 442 # @param [String] collection_name
443 443 #
444   - # @return [Hash] keys are index names and the values are lists of [key, direction] pairs
  444 + # @return [Hash] keys are index names and the values are lists of [key, type] pairs
445 445 # defining the index.
446 446 def index_information(collection_name)
447 447 sel = {:ns => full_collection_name(collection_name)}
24 test/functional/collection_test.rb
@@ -1252,12 +1252,36 @@ def test_max_scan
1252 1252 assert_nil @geo.index_information['baz']
1253 1253 end
1254 1254
  1255 + #should "create a text index" do
  1256 + # @geo.save({'title' => "some text"})
  1257 + # @geo.create_index([['title', Mongo::TEXT]])
  1258 + # assert @geo.index_information['title_text']
  1259 + #end
  1260 +
  1261 + should "create a hashed index" do
  1262 + @geo.save({'a' => 1})
  1263 + @geo.create_index([['a', Mongo::HASHED]])
  1264 + assert @geo.index_information['a_hashed']
  1265 + end
  1266 +
1255 1267 should "create a geospatial index" do
1256 1268 @geo.save({'loc' => [-100, 100]})
1257 1269 @geo.create_index([['loc', Mongo::GEO2D]])
1258 1270 assert @geo.index_information['loc_2d']
1259 1271 end
1260 1272
  1273 + should "create a geoHaystack index" do
  1274 + @geo.save({ "_id" => 100, "pos" => { "long" => 126.9, "lat" => 35.2 }, "type" => "restaurant"})
  1275 + @geo.create_index([['pos', Mongo::GEOHAYSTACK], ['type', Mongo::ASCENDING]], :bucket_size => 1)
  1276 + puts @geo.index_information['loc_geoHaystack_type_1']
  1277 + end
  1278 +
  1279 + should "create a geo 2dsphere index" do
  1280 + @collection.insert({"coordinates" => [ 5 , 5 ], "type" => "Point"})
  1281 + @geo.create_index([['coordinates', Mongo::GEO2DSPHERE]])
  1282 + assert @geo.index_information['coordinates_2dsphere']
  1283 + end
  1284 +
1261 1285 should "create a unique index" do
1262 1286 @collection.create_index([['a', Mongo::ASCENDING]], :unique => true)
1263 1287 assert @collection.index_information['a_1']['unique'] == true
2  test/unit/collection_test.rb
@@ -106,7 +106,7 @@ class CollectionTest < Test::Unit::TestCase
106 106 @coll.ensure_index [["x", Mongo::DESCENDING]]
107 107 end
108 108
109   - should "call generate_indexes for a new direction on the same field for ensure_index" do
  109 + should "call generate_indexes for a new type on the same field for ensure_index" do
110 110 @client = MongoClient.new('localhost', 27017, :logger => @logger, :connect => false)
111 111 @db = @client['testing']
112 112 @coll = @db.collection('books')

0 comments on commit 6b80321

Please sign in to comment.
Something went wrong with that request. Please try again.