2

これは、トレント インデクサーに関する他の MongoDB の質問への一種のフォローアップです。

私はオープン ソースの torrent インデクサー (本質的にミニ TPB のようなもの) を作成しており、現在、バックエンド用に SQLite と MongoDB の両方を提供しています。

ただし、MongoDB の部分に問題があります。Sinatra ではこのエラー、torrent をアップロードしたり、torrent を検索しようとしたときに取得します。

アップロードでは、トレントにタグを付ける必要がありますが、ここでは失敗します。タグを追加するコードは次のとおりです。

def add_tag(tag)
  if $sqlite
    unless tag_exists? tag
      $db.execute("insert into #{$tag_table} values ( ? )", tag)
    end
    id = $db.execute("select oid from #{$tag_table} where tag = ?", tag)
    return id[0]
  elsif $mongo
    unless tag_exists? tag
      $tag.insert({:tag => tag})
    end
    return $tag.find({:tag => tag})[:_id] #this is the line it presumably crashes on
  end
end

105 行目 (上記) に達し、その後失敗します。どうしたの?また、参考までに、解決策が登場するにつれて、これは他のいくつかの質問に変わる可能性があります.

ありがとう!

編集

そのため、タグの結果を で返す代わりに[:_id]、elsif 内のブロックを次のように変更しました。

id = $tag.find({:tag => tag})
puts id.inspect
return id

それでもエラーが発生します。デモはhttp://torrent.hypeno.deで、ソースはhttp://github.com/tekknolagi/indexer/で見ることができます。

4

2 に答える 2

4

を実行していることを考えるとinsert()、ID を取得する最も簡単な方法は次のとおりです。

 id = $tag.insert({:tag => tag})

idBSON::ObjectIdになるため、必要な戻り値に応じて適切なメソッドを使用できます。

 return id         #  BSON::ObjectId('5017cace1d5710170b000001')
 return id.to_s    # "5017cace1d5710170b000001"

元の質問では、Collection.find()メソッドを使用しようとしています。これはMongo::Cursorを返しますが、カーソルをドキュメントとして参照しようとしています。eachまたはを使用してカーソルを反復処理する必要がありますnext

 cursor = $tag.find_one({:tag => tag})
 return cursor.next['_id'];

単一のドキュメントが必要な場合は、Collection.find_one()を使用する必要があります。

たとえば、次を使用して _id を検索して返すことができます。

 return $tag.find_one({:tag => tag})['_id']
于 2012-07-31T12:30:39.233 に答える
0

ここでの問題は だと思います[:_id]。私はMongoについてあまり知りませんが`$tag.find({:tag => tag})、おそらく配列を返し、[]配列演算子にシンボルを渡すことは定義されていません。

于 2012-07-30T22:00:27.487 に答える