node.jsで、外部APIへアクセスし、mongodb内のデータと比較する方法

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 374

Royec0619

score 46

■やりたいこと
TwitterのTLデータが格納されているMongoDBに、新たにTwitterのTLデータを格納する前に、
既存のデータとTwitterの REST APIから取得したデータの{id}を比較し、一致しないデータだけ格納したい。

■できていないこと
比較する際に、APIから取得したツイートとMongoDBからfindした内容が比較できない。(undefindになってしまう。)

■わからないこと
Javascriptの仕様である非同期を理解しきれていない所為で、思うように「やりたいこと」を実現できていません。
MongoDBから取得したカーソルをtoArray()で回す際にコールバック関数を使用するのですが、こちらにTwitter APIで取得したデータの渡し方がわからない。
toArrayのコールバック関数にtweetsを渡してもうまくいかない。

■教えていただきたいこと
Node.jsで、Twitterなどの外部APIからデータを取得しつつ、すでに格納されているMongoDBのデータと比較する方法。

■環境
OS: CentOS Linux release 7.6.1810 (Core)
Node.js: v8.15.0
ライブラリ:mongodb@3.1.10、twitter@1.7.1
MongoDB: v3.4.10

'use strict';
const MongoClient = require('mongodb').MongoClient
const assert = require('assert')

const Twitter = require('twitter')

const HOSTNAME = 'mongodb://127.0.0.1:27017'
const DB_NAME = 'company'
const COLLECTION_NAME = 'members'

const client_tw = new Twitter({
    consumer_key:        '',
    consumer_secret:     '',
    access_token_key:    '',
    access_token_secret: '',
});

client_tw.get('search/tweets', function(error, tweets, response) {
    MongoClient.connect(HOSTNAME, { useNewUrlParser: true }, (err, client) => {
        const db = client.db(DB_NAME)
        const collection = db.collection(COLLECTION_NAME)

        for (var i = 0; i < tweets.statuses.length; i++) {
            collection.find().toArray(function(err, docs) {
                assert.equal(err, null)
                for (var doc of docs) {
                    if (tweets.statuses[i].id !== doc.id) { //ここでツイートと比較
                        console.log(doc.id); //デバッグのためにコンソール出力にしていますが、実際にはinsertしたい
                    }
                }
            });
        }

    });
});

他に必要な情報がありましたら、ご指摘ください。
よろしくお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

check解決した方法

0

const main = async () => {

  const client = await mongodb.MongoClient.connect(HOSTNAME, { useNewUrlParser: true })
  const db = await client.db(DB_NAME)

  try {
    const docs = await db.collection(COLLECTION_NAME).find({}).toArray()
    const tweets = await client_tw.get('search/tweets', params)

    for (var i = 0; i < tweets.statuses.length; i++) {
      for (var doc of docs) {
        if (tweets.statuses[i].id === doc.id) {
          break;
        }
      }
      console.log(tweets.statuses[i].id);
    }
  } catch(err) {
    throw err;
  }

  await client.close();
}

main();

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.21%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる