2012-11-13 2 views
2

나는 방금 루비와 mongodb의 개념을 배우기 시작했습니다. 이 스크립트는 내가 실행하려고하는 스크립트입니다MongoDB에서 tweetstream을 사용하여 트윗을 저장하면 다음 오류로 인해 실패합니다.

require 'rubygems' 
require 'tweetstream' 
require 'mongo' 

TweetStream.configure do |config| 
    config.consumer_key = '<key>' 
    config.consumer_secret = '<secret>' 
    config.oauth_token = '<token>' 
    config.oauth_token_secret = '<token_secret' 
    config.auth_method = :oauth 
end 

connection = Mongo::Connection.new 

db = connection.db("tweetsDB") 

tweets = db.collection("tweets") 

client = TweetStream::Client.new 

client.on_error do |message| 
    puts message 
end 

client.follow(<user_id>,<user_id>) do |status| 
     id = tweets.insert(status, :safe => true) 
end 

참고 :이 게시물의 위 스크립트에서 모든 정적 개인 값을 제거했습니다. 몽고, bson의

버전, bson_ext - 1.7.0

오류 메시지

NoMethodError: undefined method `has_key?' for #<Twitter::Tweet:0x7f21cd14cf08> 
    /var/lib/gems/1.8/gems/bson-1.7.0/lib/bson/types/object_id.rb:93:in `create_pk' 
    /var/lib/gems/1.8/gems/mongo-1.7.0/lib/mongo/collection.rb:360:in `insert' 
    /var/lib/gems/1.8/gems/mongo-1.7.0/lib/mongo/collection.rb:360:in `collect!' 
    /var/lib/gems/1.8/gems/mongo-1.7.0/lib/mongo/collection.rb:360:in `insert' 
    tracker.rb:28 
    /var/lib/gems/1.8/gems/tweetstream-2.3.0/lib/tweetstream/client.rb:525:in `call' 
    /var/lib/gems/1.8/gems/tweetstream-2.3.0/lib/tweetstream/client.rb:525:in `invoke_callback' 
    /var/lib/gems/1.8/gems/tweetstream-2.3.0/lib/tweetstream/client.rb:533:in `yield_message_to' 
    /var/lib/gems/1.8/gems/tweetstream-2.3.0/lib/tweetstream/client.rb:471:in `respond_to' 
    /var/lib/gems/1.8/gems/tweetstream-2.3.0/lib/tweetstream/client.rb:411:in `connect' 
    /var/lib/gems/1.8/gems/em-twitter-0.2.1/lib/em-twitter/connection.rb:296:in `call' 
    /var/lib/gems/1.8/gems/em-twitter-0.2.1/lib/em-twitter/connection.rb:296:in `invoke_callback' 
    /var/lib/gems/1.8/gems/em-twitter-0.2.1/lib/em-twitter/connection.rb:143:in `handle_stream' 
    /var/lib/gems/1.8/gems/em-twitter-0.2.1/lib/em-twitter/connection.rb:193:in `on_body' 
    /var/lib/gems/1.8/gems/em-twitter-0.2.1/lib/em-twitter/connection.rb:192:in `each' 
    /var/lib/gems/1.8/gems/em-twitter-0.2.1/lib/em-twitter/connection.rb:192:in `on_body' 
    /var/lib/gems/1.8/gems/em-twitter-0.2.1/lib/em-twitter/connection.rb:74:in `<<' 
    /var/lib/gems/1.8/gems/em-twitter-0.2.1/lib/em-twitter/connection.rb:74:in `receive_data' 
    /var/lib/gems/1.8/gems/eventmachine-1.0.0/lib/eventmachine.rb:187:in `run_machine' 
    /var/lib/gems/1.8/gems/eventmachine-1.0.0/lib/eventmachine.rb:187:in `run' 
    /var/lib/gems/1.8/gems/tweetstream-2.3.0/lib/tweetstream/client.rb:385:in `start' 
    /var/lib/gems/1.8/gems/tweetstream-2.3.0/lib/tweetstream/client.rb:128:in `filter' 
    /var/lib/gems/1.8/gems/tweetstream-2.3.0/lib/tweetstream/client.rb:106:in `follow' 
    tracker.rb:27 
+0

당신은 '수 그냥 트위터 개체를 저장하지 마십시오. 먼저 해당 객체를 YAML 또는 JSON 해시로 변환해야합니다. – Linuxios

답변

0

Client.follow 그냥 일반적인 루비 객체를 반환하는 docs 보는 것 같다. 개체에서 관련 필드를 가져 와서 json (또는 더 바람직하게는 mongoid 개체)으로 가져 와서 데이터베이스로 보내야합니다.

+0

답변 해 주셔서 감사합니다. 상태를 사용하여 특정 필드를 추출합니다. 예를 들어 status.text, status.geo와 같은 대부분은 잘 작동하지만 status.coordinates, status.contributors는 undefinedmethod 오류로 실패합니다. 왜 그런가? – user1820971

+0

대부분의 트윗 필드가 잘 전달되지만 엔티티의 경우이 오류가 발생합니다. BSON :: InvalidDocument 트위터 클래스의 객체를 직렬화 할 수 없습니다. entity :: User_Mention을 BSON으로 – user1820971

+0

잘 모르겠습니다. 죄송합니다. status.coordinates와 status.contributors가 실제로 어떤 상태인지보기 위해 디버거를 사용합니다. – shelman

0

has_key? Hash 슈퍼 클래스에서 사용 가능한 메소드입니다. 그것이하려고하는 것은 json 문자열을 Mongo로 전달하는 것입니다. 당신이 문자열을 전달하는 것을 제외하고, has_key? String 클래스의 일부가 아닙니다. 해시로 변환하면 갈 수 있어야합니다. 당신이 맹목적으로하여 MongoDB에 모든 것을 덤프하려면

client.follow(<user_id>,<user_id>) do |status| 
    id = tweets.insert({:status => status.text}, :safe => true) 
end 
2

당신은 단지 수행 할 수 있습니다

client.follow(<user_id>,<user_id>) do |status| 
    data = status.to_hash 
    id = tweets.insert(data) 
end 

당신이 다음과 같이 시도 할 수 있습니다 좀 더 선택적 싶은 경우 :

# only add the following fields to the database 
ONLY = %w{created_at text geo coordinate id_str} 

client.follow(<user_id>,<user_id>) do |status| 
    data = status.to_hash.select{|k,v| ONLY.include?(k.to_s)} 
    id = tweets.insert(data) 
end 

또는 :

# add everything except the following fields to the database 
EXCEPT = %w{entities} 

client.follow(<user_id>,<user_id>) do |status| 
    data = status.to_hash.reject{|k,v| EXCEPT.include?(k.to_s)} 
    id = tweets.insert(data) 
end 
관련 문제