Techioz Blog

cassandra Ruby : ブロックパラメーターの複数の値 (2 対 1)

概要

ビッグデータに関するチュートリアルに従おうとしていますが、cqlshで定義されたキースペースからデータを読み取ろうとしています。

このコード部分は正常にコンパイルされました。

require 'rubygems'
require 'cassandra'

db = Cassandra.new('big_data', '127.0.0.1:9160')

# get a specific user's tags
row = db.get(:user_tags,"paul")

###
def tag_counts_from_row(row)
  tags = {}

  row.each_pair do |pair|
    column, tag_count = pair
    #tag_name = column.parts.first
    tag_name = column
    tags[tag_name] = tag_count
  end

  tags
end
###
# insert a new user
db.add(:user_tags, "todd", 3, "postgres")
db.add(:user_tags, "lili", 4, "win")


tags = tag_counts_from_row(row)
puts "paul - #{tags.inspect}"

しかし、みんなのタグを出力するためにこの部分を書くとエラーが発生します。

 user_ids = []
    db.get_range(:user_tags, :batch_size => 10000) do |id|
    #  user_ids << id
    end

    rows_with_ids = db.multi_get(:user_tags, user_ids)
    rows_with_ids.each do |row_with_id|
      name, row = row_with_id

      tags = tag_counts_from_row(row)
      puts "#{name} - #{tags.inspect}"
    end

エラーは次のとおりです:

このエラーは、Cassandra と Ruby のバージョンに互換性がないことが原因である可能性があると思います。それを修正するにはどうすればよいですか?

解決策

どの行が 33 であるかを判断するのは少し難しいですが、問題は get_range が 2 つの値を生成するのに、ブロックが最初の値しか取得していないことのようです。列ではなく行キーのみを考慮する場合は、get_range_keys を使用する必要があります。

db.multi_get を使用して列の値を再度フェッチしているため、実際には列の値を気にしているようです。これは不必要な追加のクエリです。コードを次のように更新できます。

db.get_range(:user_tags, :batch_size => 10000) do |id, columns|
  tags = tag_counts_from_row(columns)
  puts "#{id} - #{tags.inspect}"
end