2013-10-12 12 views
0

Я разрабатываю аналитическую программу для данных Twitter. Я использую mongoDB и на данный момент. Я пытаюсь написать программу Java, чтобы получить твиты из API Twitter и поместить их в базу данных. Получение Tweets уже работает очень хорошо, но у меня проблема, когда я хочу поместить их в базу данных. Поскольку API Twitter часто возвращает одни и те же твиты, я должен поместить какой-то индекс в базу данных.Избегайте дублирования записей в mongoDB с объектами Java и JSON

Прежде всего, я подключаюсь к базе данных и получаю коллекцию, связанную с поисковым термином, или создаю эту коллекцию, если это не существует.

public void connectdb(String keyword) 
     { 
      try { 
       // on constructor load initialize MongoDB and load collection 
       initMongoDB(); 
       items = db.getCollection(keyword); 
       BasicDBObject index = new BasicDBObject("tweet_ID", 1); 
       items.ensureIndex(index); 



      } catch (MongoException ex) { 
       System.out.println("MongoException :" + ex.getMessage()); 
      } 

     } 

Тогда я получаю твиты и поместить их в базу данных:

public void getTweetByQuery(boolean loadRecords, String keyword) { 

      if (cb != null) { 
       TwitterFactory tf = new TwitterFactory(cb.build()); 
       Twitter twitter = tf.getInstance(); 
       try { 
        Query query = new Query(keyword); 
        query.setCount(50); 
        QueryResult result; 
        result = twitter.search(query); 
        System.out.println("Getting Tweets..."); 
        List<Status> tweets = result.getTweets(); 

        for (Status tweet : tweets) { 

         BasicDBObject basicObj = new BasicDBObject(); 
         basicObj.put("user_name", tweet.getUser().getScreenName()); 
         basicObj.put("retweet_count", tweet.getRetweetCount()); 
         basicObj.put("tweet_followers_count", tweet.getUser().getFollowersCount()); 

         UserMentionEntity[] mentioned = tweet.getUserMentionEntities(); 
         basicObj.put("tweet_mentioned_count", mentioned.length); 
         basicObj.put("tweet_ID", tweet.getId()); 
         basicObj.put("tweet_text", tweet.getText()); 


         if (mentioned.length > 0) { 
//     System.out.println("Mentioned length " + mentioned.length + " Mentioned: " + mentioned[0].getName()); 
         } 
         try { 
          items.insert(basicObj); 
         } catch (Exception e) { 
          System.out.println("MongoDB Connection Error : " + e.getMessage()); 
          loadMenu(); 
         } 
        } 
        // Printing fetched records from DB. 
        if (loadRecords) { 
         getTweetsRecords(); 
        } 

       } catch (TwitterException te) { 
        System.out.println("te.getErrorCode() " + te.getErrorCode()); 
        System.out.println("te.getExceptionCode() " + te.getExceptionCode()); 
        System.out.println("te.getStatusCode() " + te.getStatusCode()); 
        if (te.getStatusCode() == 401) { 
         System.out.println("Twitter Error : \nAuthentication credentials (https://dev.twitter.com/pages/auth) were missing or incorrect.\nEnsure that you have set valid consumer key/secret, access token/secret, and the system clock is in sync."); 
        } else { 
         System.out.println("Twitter Error : " + te.getMessage()); 
        } 


        loadMenu(); 
       } 
      } else { 
       System.out.println("MongoDB is not Connected! Please check mongoDB intance running.."); 
      } 
     } 

Но, как я уже говорил ранее, часто одни и те же твиты, и у них есть дубликаты в базе данных. Я думаю, что поле tweet_ID является хорошим полем для индекса и должно быть уникальным в коллекции.

ответ

0

Установите unique вариант на индексе иметь MongoDb обеспечения уникальности:

items.ensureIndex(index, new BasicDBObject("unique", true)); 

Обратите внимание, что вам необходимо вручную сбросить существующий индекс и удалить все дубликаты или вы не сможете создать уникальный индекс.

+0

или положить ("dropDups", true) на этот BasicDBObject, который вы проходите. – evanchooly

0

Этот вопрос уже ответил, но я хотел бы внести свой вклад немного, так как MongoDB API 2.11 предлагает метод, который получает уникальный параметр в качестве параметра:

public void ensureIndex(DBObject keys, String name, boolean unique) 

Несовершеннолетний напомнить кому-то, кто хотел бы хранить JSon документы MongoDBNote заключается в том, что уникальность должна применяться к ключу BasicObject, а не по значениям. Например:

BasicDBObject basicObj = new BasicDBObject(); 
basicObj.put("user_name", tweet.getUser().getScreenName()); 
basicObj.put("retweet_count", tweet.getRetweetCount()); 
basicObj.put("tweet_ID", tweet.getId()); 
basicObj.put("tweet_text", tweet.getText()); 
basicObj.put("a_json_text", "{"info_details":{"info_id":"1234"},"info_date":{"year":"2012"}, {"month":"12"}, {"day":"10"}}"); 

Об этом случае, вы можете создать уникальный индекс только для основных ключей объекта:

BasicDBObject index = new BasicDBObject(); 
int directionOrder = 1; 
index.put("tweet_ID", directionOrder); 
boolean isUnique = true; 
items.ensureIndex(index, "unique_tweet_ID", isUnique); 

Любой индекс относительно значения JSON, как «info_id» не будет работать, так как не подмигнули Ключ BasicObject.

Использование индексов на MongDB не так просто, как кажется. Вы также можете проверить документы MongoDB для получения дополнительной информации здесь Mongo Indexing Tutorials и Mongo Index Concepts. Порядок направления может быть очень важным для понимания, когда вам нужен сложенный индекс, который здесь хорошо объясняется Why Direction order matter.

Смежные вопросы