TakayukiKoyama Geek Blog

Create, Entertain, Experience

【Mongo, Nodejs】ObjectIdでCollection同士をJoin(aggregate)するときの注意

CollectionをJoinしたい

  • 前提:mongooseではなくMongoClient
  • 例:Userコレクションのid(ObjectId)と Eventコレクションのuser_id(UserのidをInsert)をJoinする
// 色々省略:collectionはMongoClientで作った対象のコレクションを呼び出すメソッド
const COL = 'event';
collection(COL).aggregate(
  [
    { $match: { privacy: 'community' } },
    { $lookup: {
        from: 'user', // 結合対象のコレクション
        localField: 'user_id', // 結合元のコレクションフィールド
        foreignField: '_id', // 結合先のコレクションフィールド
        as: 'admin' // 結合結果のフィールド名
      }
    },
    { $unwind: "$admin" } // 配列でなく1ドキュメントになる場合は $unwind を指定
  ]
).toArray(function(err, docs){
    // WebAPIにする場合の記述
    if (err) {
        throw err;
    }
    res.writeHead(200, { 'Content-Type': 'application/json' });
    res.end(JSON.stringify(docs));
})

注意すべき点

上記の方法でJoinしようとした場合、UserのidはObjectIdとなる。
(例:"
id": { “$oid”: “5985ef58ab567258537d6ac5” })

そのため、Eventコレクションに格納したuser_idがObjectIdではなく文字列にすると、_idとuser_idが一致しないため結果は空になる。
(例: “user_id”: “5985ef58ab567258537d6ac5")

調べてみたところ、StackOverflow的にはaggregate内で 文字列 -> ObjectId 変換させることはできないらしい。

参考:join - How to convert string to objectId in LocalField for $lookup Mongodb - Stack Overflow

解決策

現状の解決策は、Eventコレクションのuser_idにObjectIdを入れるしかない。

EventコレクションにInsertするときに以下のようにする。

// 文字列 -> ObjectId変換
req.body.user_id = new ObjectID( req.body.user_id );
collection(COL).insertOne( req.body ).then(function(doc) {
    // WebAPIのレスポンス処理
    res.writeHead(200, { 'Content-Type': 'application/json' });
    res.end(JSON.stringify(doc));
});

↑ user_id文字列をObjectIdに変換して保存。

もう少しスマートな書き方がありそうな気もする。それは思いついたら書きます。

会社設立とReact Nativeでアプリ開発することについて

久しぶりにブログを更新します。

概要

今年5月に会社を立ち上げ、取引先のAndroid/iOSアプリを7/7にリリースしました。

会社立ち上げ

約2年半フリーランスエンジニアを経て合同会社を設立しました。設立前の想定していた売上よりは少ないですが、おかげさまで5月〜6月は黒字でひとまず順調です。

今月は今回得られたReactNativeの経験を活かして自社サービス開発と取引先のアプリの機能改善やリファクタリング、不具合対応を進めていく予定です。

ReactNativeのアプリ開発

7/7に初めてチャレンジしたReactNativeでAndroid/iOSアプリをリリースしました。

もともとAndroidアプリ開発を5年以上経験していて、サーバサイド/フロントエンド/サーバ構築などもエキスパートではないですが、一通りこなせるのでReactNativeでアプリ開発もできるかなと思いましたが、思いの外苦戦しました。

取引先ではWebサービスを展開しており、モバイル対応のWebアプリも提供していますが、Push通知などでもっとユーザの目に触れる機会を増やしたいということでアプリ開発をすることになりました。

今まで数年かけて作り上げてきたWebサービスの機能のほとんどを開発期間も2ヶ月(実際は調査期間が+1ヶ月半の業務時間外)で開発することになったのでかなり工夫が必要でした。

そのへんについてはまたどこかで書きます。

これからやろうとすること

ReactNetiveがかなり高速にアプリを開発できて、Objective-C/Swiftは全くわかってなくてもiOSアプリが作れるので、今まで後回しにしていたアイデアのプロトタイプを作ります。

最近読んだ本

怒らない経営 しがらみを超え、地元を盛り上げる!

怒らない経営 しがらみを超え、地元を盛り上げる!

以前カンブリア宮殿に出演していた大藪さんの本が出ていることを知ったので読んでみた。異色の経歴ながらも愛媛を盛り上げることに全力で取り組んでいて凄い人だと思う。

決断すべきときは従業員がやる気の出る方を選択するという迷いのない判断は見習いたい。

多動力 (NewsPicks Book)

多動力 (NewsPicks Book)

「1晩で10件ハシゴしろ」の内容は、これ自分もやりたいなと思った。というか、回転率上がるんだから、こういうの最適化したサービス作ったらいいと思う。今作ってるアプリが終わったあとに誰もやってなかったらやりたい。

最近興味をもったサービス

Valu:VALU | システムメンテナンス

自分のValu:VALU | Takayuki KoyamaのVALU

分かりやすい記事:VALUとは何か?【すごく分かりやすく説明してみた】 - それ、僕が図解します。

個人の価値を株式のようにトレードするサービス。自分もアカウントを作ってみましたが、審査中なのでたぶん他の人はまだ見れないかも。

完全に放置していたビットコインをそのままこっちに移してみました。

Oracle Java 8 SE Silver & Gold を取得した話

Goldを合格して1ヶ月経ってしまったが、一応書いておこうと思う。

マイスペック

Java関連で言うと

情報工学系大でJavaの授業を受けた

Androidアプリ開発を6年程度

Java Strutsの開発を1年程度

Silver

 Javaに慣れ親しんでいるとはいえ、勉強したのは入門書を一通り読んだり、Effective Java を掻い摘んで読んだりしているレベルなので、Bronzeから勉強した。Bronzeは勉強はしたが受験せず、読み終えたらSilver本に切り替え。

徹底攻略 Java SE 7/8 Bronze 問題集[1Z0-814]対応

徹底攻略 Java SE 7/8 Bronze 問題集[1Z0-814]対応

徹底攻略 Java SE 8 Silver 問題集[1Z0-808]対応

徹底攻略 Java SE 8 Silver 問題集[1Z0-808]対応

 ひたすら黒本を読んだ。Bronze&Silverに関しては、ほとんど手を動かさずに読むだけしかしなかった。知ってる知識が多いので特に書くほどでもないかなと。

Silverの結果

 スコア:92% / 合格:65% / 満点:100%

 黒本によく似た問題がたくさん出たのでサクサク解いて、40分ぐらい余って退出した。

Gold

 Goldも変わらず、黒本。

徹底攻略 Java SE 8 Gold 問題集[1Z0-809]対応

徹底攻略 Java SE 8 Gold 問題集[1Z0-809]対応

 黒本の著者がOracleオフィスのセミナールームで Java 8 SEの講習を開催していたので参加。自分は本のページ捲ったり、背表紙を折り曲げたりしてボロボロで汚かったが、参加者の殆どは新品に近い感じで読む前に受講する人が多いのかなという印象だった。

 ボロボロにしたものの、1回目の試験失敗。自暴自棄になりながら、丸善で黒本になく試験に似たような問題がいくつかあった白本を買って、間違えた分野のコードは必ず書いた。

オラクル認定資格教科書 Javaプログラマ Gold SE 8 スピードマスター問題集

オラクル認定資格教科書 Javaプログラマ Gold SE 8 スピードマスター問題集

Gold1回目の結果

 スコア:57% / 合格:65% / 満点:100%

 なぜか、すごくテンパってしまって、冷静に問題を解けず慌てながら解答して時間一杯使っても点が取れなかった。油断もあったが、合格点は超えてるだろうと思っていたので、正直ショックだった。

Golde2回目の結果

 スコア:83% / 合格:65% / 満点:100%

 再試験は2週間待たないといけないので、2週間後に再受験。不合格のときに間違えた分野を重点的にコードを何度も書いて理解を深めた。特に Stream APIラムダ式関係。関数インタフェース、無名クラス、ラムダ式、メソッド参照の変換はパパっとできるようにした。

勉強期間

・Silver:Bronze&Silverを1ヶ月半掛けて読んで受験して合格

・Gold:黒本を1ヶ月読んで受験して落ちて、2週間白本と間違えた分野をググってコード書いて2回目の受験で合格

Oracle Javaの注意点

・再試験無料キャンペーン申し込み

 これは1回目の申込みのときに適用する必要がある。恥ずかしながらよく分かってなくて、1回目に適用せず2回目の受験料も払う羽目になった。予定外の出費。正直、そこまで払って取りたい資格でもないから2回目の支払いのとき受験を止めるかどうか滅茶苦茶悩んだが、せっかく勉強したので区切りをつけないと後味が悪いなと思って受験した。とはいえ、受験しても後味が悪かったw だいたい、Gold取ったからなんだっていう話しなわけで。

 Javaの仕事の紹介をしてくれる人がいたので、そういうときに信頼してもらえるというメリットはなくもない。仕事受けたわけじゃないけど。

Oracle ID

 確かOracleのピアソンVUEにサインインすれば、右上あたりに表示されたはず。Ciscoに比べると面倒じゃなかったはず。   Oracle :: ピアソンVUE

最後に

 Javaはこれからも付き合っていくだろうから良い関係を築きたい。

Mac OSX で Rails における neo4j の 環境構築

インストール

 インストール方法は2つある。

brew

$ brew install neo4j

インストーラをダウンロード

Download Neo4j Community Edition - Neo4j Graph Database

 brewは簡単だが、バージョンが2.x系で認証関係がうまく動作しなかったので、3.x系のインストーラをダウンロードした。

Rails設定

 Gemfileを設定する。

$ vim Gemfile
gem 'neo4j', '~> 7.0.0'
gem "net-http-persistent", "< 3.0"

$ bundle install

 'net-http-persistent' をつけたのは「Rails `initialize': wrong number of arguments (given 2, expected 0) (ArgumentError)」が発生しないようにするため。エラーが発生しないならつけなくていい。

参考:Bountysource

 config/application.rbにneo4jを追加。

$ vim config/application.rb
# ...
require 'neo4j/railtie'

class Application < Rails::Application
  # ...

  config.generators { |g| g.orm :neo4j }
end

 config/neo4j.ymlにneo4jのpath指定。

$ vim config/neo4j.yml
development:
  type: http
  url: http://neo4j:password@localhost:7474

test:
  type: http
  url: http://localhost:7575

production:
  type: http
  url: http://neo4j:password@localhost:7000

 これでModelを作って、データを投入できる。

Mac OS X環境のMongodbアップデート(2.4→3.2)

備忘録

 まずはmongoの配置場所を確認。brewだと場所が違うかも。

$ which mongo
/opt/mongodb/mongodb-osx-x86_64-2.4.13/bin/mongo
$ mongod --version
db version v2.4.13

 mongodb3.2をダウンロード。wgetがインストールされてなかったw

$ cd /opt/mongodb/
$ brew install wget
$ sudo wget https://fastdl.mongodb.org/osx/mongodb-osx-x86_64-3.2.0.tgz
$ sudo tar xvfz mongodb-osx-x86_64-3.2.0.tgz

 一旦、mongodbを停止する。

$ mongo
> use admin
> db.shutdownServer();
> quit();

 mongodbの環境変数を変更

$ vim ~/.bash_profile
#export PATH="/opt/mongodb/mongodb-osx-x86_64-2.4.13/bin:$PATH"
export PATH="/opt/mongodb/mongodb-osx-x86_64-3.2.0/bin:$PATH"
$ source ~/.bash_profile

 バージョン確認

$ which mongo
/opt/mongodb/mongodb-osx-x86_64-3.2.0/bin/mongo
$ mongod --version
db version v3.2.0

 mongodb再起動。dbpathの配置場所は前回に合わせるか、新規で設定する。

$ sudo mongod --fork --logpath /opt/mongodb/log/mongodb.log --nojournal --noprealloc --dbpath /opt/mongodb/db

 mongo起動。

$ mongo
> show databases

Herokuにデプロイしたときの「Precompiling assets failed.」エラーについて

久々に Heroku を使ったら、完全に手順を忘れた。

新しくRailsアプリ作ってデプロイすると、Herokuの「Activity」に以下のエラーが出てうまくいかない。

       Tasks: TOP => assets:precompile
       (See full trace by running task with --trace)
 !
 !     Precompiling assets failed.
 !
 !     Push rejected, failed to compile Ruby app.
 !     Push failed

 一見すると、assets:precompileの設定の問題かなと思ったが、ログをスクロールしていくと以下のようなエラーがある。(エラー内容はプロジェクトによって異なる)

       rake aborted!
       Sprockets::FileNotFound: couldn't find file 'xxx.png'
       (in /tmp/build_xxxxx/<AccountName>-<AppName>-xxxxxx/app/assets/stylesheets/application.css.scss)

 エラー内容はググる等で解決するとして、そもそもローカル環境上でもproduction時のassets:precompileもエラーになっていた。ローカル上で成功すれば、heroku側も成功するはずなので、ローカル上のassets:precompileが正常に動くようにしてからデプロイすると良い。

$ RAILS_ENV=production bundle exec rake assets:precompile

 ちなみに、「Precompiling assets failed.」でググると「config/application.rb」の「config.assets.initialize_on_precompile = true」をfalseにするようにみたいなことを書いてあったりするが、Rails4ではむしろtrueじゃないと通らなかった。

ある分野が0点でも合格できたCCNA ICND2、それでいいのCiscoさん?

>>> ICND1の話しはこちら

今日の朝、ギリギリまで勉強してAM11:30にICND2を受験しに行ってきた。

ICND1は90分だが、ICND2は75分なので正直、全問解けるか不安だったが、焦りながら分からないものは分からんという感じで尤もらしい解答を入力してなんとか合格した。

結果はICND2と同じ点数だった。正直危ない点数。LPICの頃から思うが、よくいつもギリギリな点数で1発合格できるなと自分に感心しつつも、なぜあれだけ勉強しても高得点が取れないのかと勉強スタイルや時間を見直す必要があるなと思ったりしたり。

勉強期間も前回と変わらず1ヶ月半(7月後半〜8月末)。

結果

ICND2

・53問

・スコア:854点

・合格点:825点

・満点:1000点

ちなみに試験範囲の6%を占める[IP Services]が0%(0点)だったwww

f:id:tkoyama1988:20160828233626j:plain

問題数が少ないとはいえ、これは宜しくない気がする。

ちなみに試験範囲の配分はこちらに記載されている。配分に応じて勉強量を調整してもいいかもしれない。

200-101J ICND2 - IT 認定とキャリアパス - Cisco Systems

Cisco語とかそういうレベルじゃない翻訳がひどい問題がたくさんある。

コマンドを日本語に翻訳している。

とか、

文章が明らかにおかしくて問題の意図がわからない。

とか、見た瞬間に「日本語でおk?」な問題が10問ぐらいあった。

9/24から試験範囲が改定されるらしいので、問題の翻訳家にも予算を投じて欲しいですね。

ベース知識取得のための勉強方法

ベース知識はICND1と同じで頼りにしている書籍とPing-tを全部銀にして、模擬試験を2回ぐらい解いて、間違えた問題を理解し直す。

最短突破 Cisco CCNA Routing and Switching ICND2 合格教本 [200-120J,200-101J対応]

最短突破 Cisco CCNA Routing and Switching ICND2 合格教本 [200-120J,200-101J対応]

レビューには読みにくいという評価があったが、特に自分はそういう印象はなかった。

強いていうなら、NetFlowの説明が少ない。

シミュレーションのための勉強方法

最初は実機を使ったり、GNS3を使ってみたりしたが、準備や手順が分かりにくくて他の方法を探していたところ、Ping-tの合格体験記を見ていたらCiscoのPacket Tracerを知り、試してみたら使いやすかったので、全範囲のコマンドを出来るだけ叩いてみた。

ただ問題をやってみて分かったが、ネットワーク構築する問題はないので、show系コマンドに慣れればいいと思う。参考になるshow系コマンド一覧を記載している体験記を以下に載せておく。

引用元:おめでとう♪合格体験記-3週間かかって合格

 OSPF

 ・show ip interface brief

 ・show interfaces

 ・show ip ospf intesface

 ・show running-config

 ・show ip ospf neighbor

 ・show ip route

 EIGRP

 ・show ip interface brief

 ・show ip route

 ・show ip eigrp neighbors

 ・show runninng-config

 ・show ip eigrp topology

 SPANNING-TREE

 ・show spanning-tree

 ・show cdp neighbors

 FrameRelay

 ・show frame-relay map

 ・show frame-relay pvc

大体↑のコマンドの叩き方と用途を理解していれば問題は回答できると思う。

ちなみにFrame-relayコマンドの練習をしたいときのPacket tracerの構築手順は以下のサイトを参考にした。

How to configure frame relay in Cisco Packet Tracer - Jesin's Blog

余談

最後の問題で8分余ったが、スパニングツリープロトコルのルートポート問題の回答が足りなくて(たぶん自分が間違えてる)、8分全部費やした。