2012-04-23 91 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