2012-04-23 81 views
0

我用下面的代码来获取蒙哥东西:宝石蒙戈1.6.2返回错误值的计数(光标)

class BlockingMongoFetcher 
    include MongoConfig 

    def initialize 
    configure 
    @connection = Mongo::Connection.new(@server, @port) 
    @collection = init_collection(@connection) 
    end 

    def fetch(value) 
    mongo_cursor = @collection.find({ KEY => value.to_s }) 

    if mongo_cursor.count == 0 
     # do stuff 
     return nil 
    end 

    if mongo_cursor.count > 1 
     # do stuff 
    end 

    mongo_cursor.first 
    end 
end 

init_collection只是得到数据库,并从连接的集合对象。 在获取方法中,我使用count方法来检查是否有结果。因为我有一个0,其中应该有1个项目,我添加宝石内下面的代码来Cursor类的计数方法:

if response['n'].to_i == 0 
    require "ruby-debug" 
    debugger 
    puts "stop here" 
end 

(响应= @ db.command(命令))

在调试器

@db.command(command)['n'].to_i 

返回1。如果我的获取方法(一旦不使用输出)调用两次计一切都很好。我错过了什么吗?缓冲区还是缓存问题?但是,这似乎不是确定性的......它只发生在大约50%的运行中。 Mongodb是2.0.2和Ruby 1.9.3p125。

感谢您的帮助!

+0

在你的问题,请您谈一下使用'count',但甚至没有出现在你的代码...请尝试构建一个最小的例子,其中的问题出现,使人们能够理解你的问题,找到解决办法。 – 2012-04-23 13:44:19

回答

0

MHH,意想不到溶液:

为了插入测试数据,我使用的spec

collection.insert @hash 
内下面的语句

插入方法有一个选项:安全,请参阅API。使用默认值(false),mongodb将其存储为异步并继续执行代码。这可能会导致奇怪的行为,例如,如果您之后立即查询,则该值尚未存入数据库。只需使用

collection.insert @hash, :safe => true 
0

我怀疑你在某个地方有错误,并建议你检查游标查询的结果(例如,p collection.find(query).to_a)与集合(例如p collection.find.to_a) 。以下对Ruby 1.9.3,Mongo 2.0.4,mongo-ruby-driver 1.6.2适用。我希望它有帮助,也许你可以验证它对你有用,并且可以融合在一个解决方案上。

MongoConfig.rb

require "mongo" 

KEY = 'my_key' 

module MongoConfig 
    SERVER = 'localhost' 
    PORT = Mongo::Connection::DEFAULT_PORT 
    DB = 'my_db' 
    COLLECTION = 'my_collection' 

    attr_accessor :db, :collection 

    def configure 
    @server = SERVER 
    @port = PORT 
    end 

    def init_collection(connection) 
    @db = connection[MongoConfig::DB] 
    @collection = @db[MongoConfig::COLLECTION] 
    return @collection 
    end 

end 

blocking_mongo_fetcher_test.rb

$LOAD_PATH.unshift(File.expand_path("..", __FILE__)) 

require "test-unit" 
require "MongoConfig" 
require "BlockingMongoFetcher" 

class BlockingMongoFetcherTest < Test::Unit::TestCase 

    def setup 
    clear_collection 
    end 

    def clear_collection 
    Mongo::Connection.new[MongoConfig::DB][MongoConfig::COLLECTION].remove 
    end 

    def count_various_ways_and_cursor_twice_test 
    value = 'my name' 
    query = {KEY => value} 
    count_command = {'count' => MongoConfig::COLLECTION, 'query' => { KEY => value} } 
    fetcher = BlockingMongoFetcher.new 

    assert_equal(0, fetcher.collection.count) # collection count 
    assert_equal(0, fetcher.collection.find(query).count) # cursor count 
    assert_equal(0, fetcher.db.command(count_command)['n'].to_i) # db command count 
    assert_nil(fetcher.fetch(value)) 

    fetcher.collection.insert({KEY => value}) 
    fetcher.collection.insert({KEY => 'x'}) 

    assert_equal(2, fetcher.collection.count) # collection count 
    assert_equal(1, fetcher.collection.find(query).count) # cursor count 
    assert_equal(1, fetcher.db.command(count_command)['n'].to_i) # db command count 
    assert_equal(value, fetcher.fetch(value)[KEY]) 

    cursor = fetcher.collection.find(query) 
    assert_equal(1, cursor.count) # check once 
    assert_equal(1, cursor.count) # check twice 
    end 

    test "basic test" do 
    count_various_ways_and_cursor_twice_test 
    end 

    test "repeated test" do 
    100.times do 
     clear_collection 
     count_various_ways_and_cursor_twice_test 
    end 
    end 

end 
+0

Thx Gary,你说得对。我可以设法像你一样进行类似的测试。那么它肯定是我拥有的测试环境的一个问题。应该在之前提到过这个...代码在rspec中运行spork和一些其他库。我要检查这个方向并更新(或回答:-))这个问题。 – mosen 2012-04-24 12:35:41