質問をすることでしか得られない、回答やアドバイスがある。

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

ただいまの
回答率

90.01%

(Node.js)MongoDBで特定のキーのバリューのみ出すには

解決済

回答 1

投稿 編集

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

ryota8976

score 18

前提・実現したいこと

Node.jsでmongoDBの検索をしています。
ある特定キーに対するバリューのみを出したいのですが、うまくいきません。
調べてみても、例えばdist:1のものを出力するようにするものはありますが、distの値そのものを出力させるものは見当たりません。
全体のドキュメントは表示できる状態ですので検索の仕方がわからないという問題だとおもいます。
MongoDBには以下のようにid、dist(配列)、rot(配列)が入っています。
これらのdist、rotの配列のみを変数に格納したいのですが、どのようにすればいいでしょうか。
分かる方がいましたら、回答お願いします。

[{
 id:~~~,
 dist:[ 457,
        442,
        ・・・
      ],
 rot:[0.01,
      0.14,
      ・・・
     ]
}]

該当のソースコード

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

            // Connection URL
            const url = 'mongodb://localhost:27017';

            // Database Name
            const dbName = 'study';

            //結果
            var result=new Array();

            const client = new MongoClient(url,{useNewUrlParser: true});
            // Use connect method to connect to the server
            client.connect(function(err) {
                assert.equal(null, err);
                console.log("Connected correctly to server");

                const db = client.db(dbName);

                findDocuments(db, function() {
                    client.close(); 
                });
            });

            const findDocuments = function(db, callback) {
                // Get the documents collection
                const collection = db.collection('user');
                // Find some documents
                collection.find({}).toArray(function(err, docs) {
                assert.equal(err, null);
                console.log("Found the following records");
                for (var document of docs) {
                    console.log("Found the following records");
                    //console.log(document[dist]);
                    //console.log(document[rot]);
                    //result=push(document.dist);
                    //result=push(document.rot);
                }
                //console.log(docs)
                callback(docs);
                });
            }

試したこと

document.dist
document[dist]
これらはエラーになりました。

補足情報(FW/ツールのバージョンなど)

mongodb:4.0.10
OS:Ubuntu

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

0

例えばdist:1のものを出力するようにする

少々細かい指摘になっていまいますが、
まずはJavaScript世界の型に関して強くなるべきでしょう。
distはデータ型的には数値の配列という扱いになります。

ですのでdist:1のものを出力するという要件を出されると、
DocumentのMatch an Arrayを使えば良いのでは?という反応になりますし、
実は他の事がしたいはずなのに日本語がおかしくて上手く説明出来ないのだろうか???と回答者側が混乱してしまいます。

document.dist
document[dist]
これらはエラーになりました。

document[dist]のdistは変数名です。
文字列で指定するならばdocument.distでなければなりません。

そこから先は真っ先にconsole.log(document)を叩くべきだと思います。
もしかするとnullundefinedのようなキーが持てずに、
キーに対してアクセスを試みた瞬間エラーになるものもありますからね。

ある特定キーに対するバリューのみを出したいのですが、うまくいきません。

例題にある[{}, {}, ... {}]のデータ構造はオブジェクトの配列と呼びます。
オブジェクトの配列、つまり配列なので配列が所持しているメソッドが利用できるはずです。

JavaScriptにはArray.prototype.mapが存在するので、
配列を走査して特定の値の配列に変換するということが楽勝で行えます。
(Array.prototype.mapの理解が難しいようであれば、現段階ではfor文でちくちく回しても良いと思います)

なのでMongoDBは検索に注力して、
値の加工はJavaScriptで行うというアプローチで十分です。

ちょっとMongoDBからdataという引数で値を取り出した想定で、
distの配列だけを抜き出してみましょうか。

const data = [
  {
    id: 123,
    dist: [457, 442, 583],
    rot: [0.01, 0.14, 0.28]
  },
  {
    id: 234,
    dist: [547, 424, 853],
    rot: [0.11, 0.24, 0.38]
  }
];
const results = data.map(obj => obj.dist);
console.log(JSON.stringify(results, null, 2));
[
  [
    457,
    442,
    583
  ],
  [
    547,
    424,
    853
  ]
]

できました。
obj => obj.distというのはアロー関数と呼ばれる書き方です。
このように即興で関数を作れるのでArray.prototype.map等のようなメソッドの使い勝手は非常に良くなっています。


より高度な値の加工もおまけで追記します。

例では検索結果からdistの結果を取り出して二次元配列にしましたが、
更にこれを潰して1次元配列を取り出したいという要望になると困難です。

なのでLodash
のような値を加工するライブラリを導入してみるのも良いと思います。

例えばLodashにはflattenという二次元配列を潰して1次元配列にするような機能も存在しますので、
さっき話したdistの結果を取り出して二次元配列にてから1次元配列に潰すという要件も瞬殺です。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/08/01 10:59

    長文コメントありがとうございます。
    日本語がおかしな部分がありました。直しておきます。
    また、console.log(document)で表示されたのが、自分が投稿している一つ目のコードなのでdocument自体は参照できていると思われます。
    「MongoDBは検索に注力して、値の加工はJavaScriptで行うというアプローチ」という考え方には納得しました。
    map関数、Loadashも試してみたいと思います。
    ご丁寧に説明していただいてありがとうございます。

    キャンセル

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

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