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

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

新規登録して質問してみよう
ただいま回答率
85.48%
MongoDB

MongoDBはオープンソースのドキュメント指向データベースの1つです。高性能で、多くのリトルエンディアンシステムを利用することができます。

Q&A

解決済

1回答

1383閲覧

mongoDBでcountしたい

退会済みユーザー

退会済みユーザー

総合スコア0

MongoDB

MongoDBはオープンソースのドキュメント指向データベースの1つです。高性能で、多くのリトルエンディアンシステムを利用することができます。

0グッド

0クリップ

投稿2018/01/07 09:16

編集2018/01/07 15:40

mongodb version v3.6.1

こういうしょうもない設計のレコードが50万件くらいあります。

mongoDB

1{ 2 "_id" : ObjectId("5a51d36bf7a162fcfea3d119"), 3 "detail" : { 4 "shop_id" : 3, 5 "keyword" : "s_1", 6 "s_1" : { 7 "hoge" : false, 8 } 9 } 10}, 11{ 12 "_id" : ObjectId("5a51d36bf7a162fcfea3d111"), 13 "detail" : { 14 "shop_id" : 134, 15 "keyword" : "s_2", 16 "s_2" : { 17 "hoge" : true, 18 } 19 } 20}, 21{ 22 "_id" : ObjectId("5a51d36bf7a162fcfea3d112"), 23 "detail" : { 24 "shop_id" : 569, 25 "keyword" : "s_3", 26 "s_3" : { 27 "hoge" : true, 28 } 29 } 30}

これをmongoDB上だけで「"hoge" : true」の数をカウントしたいです。
上記のデータの場合「2」ということになります。

単純にカウントするだけなら簡単なのですが、問題は"detail"のs_1、s_2、s_3が全部uniqueな値なので、単純に

mongoDB

1"detail.s_1.hoge" : true

という条件式が書けません。

ただし、s_1、s_2、s_3というフィールド名は、必ず"detail.keyword"の値と同じです。

何か策はないものでしょうか。。。

フィールド名を$renameで変更してtemp collectionを作ろうかとも思ったのですが、やはりs_1、s_2、s_3がuniqueな値であるところでつまづきます。

レコード数が多いのでnode.jsやPHPなどは使わず、mongoDB内で完結するのがミッションです。

 
追記:
いきなりカウントするのは無理そうなので、いったん別のcollectionにフィールド名を修正して書き出そうとしてみました。

まだ途中なのでoutのところは書いていないですが、フィールド名を上書きする部分だけを書いてみました。

mongodb

1db.test.find().forEach(function(doc){ 2 let shopName = doc.shop_detail.key; 3 shopName = "shop_detail." + shopName; 4 db.test.update( { "_id" : doc._id }, { "$rename": { shopName:"shop_detail.data" } } ); 5})

エラーは出ないのですが上書きもされません。
う〜ん、ちょっと行き詰まっているのでどなたか助けてください。。。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

上のコードですが、mongoの$renameはフィールド名に変数を指定できないみたいです。
なので、temp_collectionを別に作って該当のフィールドをrootに追加してから、いらないフィールドを全部削除して"hoge" : trueをカウントしました。

ダミーのcollectionの名前はtestです。

mongodb

1db.test.find().forEach(function(doc){ 2 let str = doc.detail.keyword; 3 let bson = doc["detail"][str]; 4 db.test.update({"_id" : doc._id},{"$set" : {"data" : bson},"$unset" : {"detail" : 1}}); 5})

実行すると、

mongodb

1{ 2 "_id" : ObjectId("5a51d36bf7a162fcfea3d119"), 3 "data" : { 4 "hoge" : false 5 } 6} 7{ 8 "_id" : ObjectId("5a51d36bf7a162fcfea3d111"), 9 "data" : { 10 "hoge" : true 11 } 12} 13{ 14 "_id" : ObjectId("5a51d36bf7a162fcfea3d112"), 15 "data" : { 16 "hoge" : true 17 } 18}

その後、

mongodb

1db.test.find({"data.hoge":true}).count()

で2が返ってきます。

monboDBでフィールド名をuniqueにするのは極力やめましょうw
あー疲れた、3連休が消えた・・・。

投稿2018/01/07 17:37

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問