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

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

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

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

NoSQL

NoSQL(not only SQL)は、リレーショナルデータベース管理システムとは異なるデータベースシステムを指す言葉です。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

Express

ExpressはNode.jsのWebアプリケーションフレームワークです。 マルチページを構築するための機能セットおよびハイブリッドのWebアプリケーションを提供します。

Q&A

解決済

1回答

3056閲覧

node+Express+mongodb でDBから正常に値が取得できないことがあり困ってます

terry-0121

総合スコア12

MongoDB

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

NoSQL

NoSQL(not only SQL)は、リレーショナルデータベース管理システムとは異なるデータベースシステムを指す言葉です。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

Express

ExpressはNode.jsのWebアプリケーションフレームワークです。 マルチページを構築するための機能セットおよびハイブリッドのWebアプリケーションを提供します。

0グッド

1クリップ

投稿2016/02/01 02:07

編集2016/02/01 02:11

###前提・実現したいこと
アマゾンのAPIを叩いて、
商品データをDBに格納するシステムを組んでおります。

いま実現したいのは、そのシステムの管理画面で、
DBにアクセスしてデータを取得してフォームを表示、
フォームでsubmitされたら
フォームのデータをPOSTで受け取ってDBに格納する処理です。

node+Express+mongodb、稼働サーバ環境はcentos、
開発環境はmac(elCapitan)です。

###発生している問題・エラーメッセージ

DBから正常な値が取得できないことがあり、困っております。
以下に処理内容を記載します。

router.getが初回アクセス時の処理です。
DBから値をとってきてて、index.ejsを描画する処理です。
(プロミスはあまり意味がない状態になっていると思いますが、いろいろ試行錯誤した跡なのでできればスルーしていただけると)
router.post('/'・・・がPOST時の処理です。

フォームから受け取った値をdb_updateで更新して、
res.redirectでページを再表示させるように組んでいますが、
doc.saveした後に

AmazonDB.where().sort({'_id':'asc'}).exec(function(err,docs){
で再度DBにアクセスしてindexを描画する形をとっています。

ただ、saveの処理が完了していないうちに読みに行ってしまっているからだと思いますが、サーバ環境によっては正常な値がかえってきません。
(macでは動くけど、centosではダメだったり)

ページをリロードすると正常な値で表示されます。

これをうまく回避するにはどうしたらよいでしょうか。
お知恵を拝借できれば幸いです。

###ソースコード
var express = require('express');
var router = express.Router();

var http = require('http');
var ejs = require('ejs');
var qs = require('querystring');
var server = http.createServer();

var Promise = require('bluebird');

const ITEM_MAX=40;

var mongoose = require('mongoose');
var AmazonSchema = new mongoose.Schema({
asin: String,
url: String,
title: String,
monitoring: String,
starttime: String
});

var url = 'mongodb://localhost/ama';
var db = mongoose.connect(url);
var AmazonDB=db.model('ama',AmazonSchema);

// 初回アクセスの処理
router.get('/', function(req, res, next) {

var get_DB = new Promise(function (resolve, reject) {
AmazonDB.where().sort({'_id':'asc'}).exec(function(err,docs){
if (err) {
reject(error);
} else {
resolve(docs);
}
});
});

get_DB.then (function (docs) {
res.render('index', { title: 'Express', json: docs });
});
});

// postの処理 ---- ★1
router.post('/', function(req, res, next) {

for (i=0; i<ITEM_MAX; i++){ eval('var id=req.body.id'+i+';'); eval('var asin=req.body.asin'+i+';'); eval('var url=req.body.url'+i+';'); eval('var title=req.body.title'+i+';'); eval('var monitoring=req.body.monitoring'+i+';'); eval('var starttime=req.body.starttime'+i+';'); // タイトル、asin、urlの中身が空だった時はskip if(asin==null || url==null || title==null) { continue; } db_update(id,asin,url,title,monitoring,starttime); } res.redirect('/');

});

function db_update(id,asin,url,title,monitoring,starttime) {

AmazonDB.findOne({
'_id':id
},function(err,doc){
if (err){
console.log(err);
}
doc.id=id;
doc.asin=asin;
doc.url=url;
doc.title=title;
doc.monitoring=monitoring;
doc.starttime=starttime;

doc.save(function(err) { if (err){ console.log(err); } }).then();

});
}

###補足情報(言語/FW/ツール等のバージョンなど)
環境はcentos7、node v0.10.36、Express4.13.1、mongodb@2.1.4
mongoose@4.3.7です。

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2016/02/01 12:45

こちらの質問が他のユーザから「問題・課題が含まれていない質問」という指摘を受けました teratailでは、漠然とした興味から票を募るような質問や、意見の主張をすることを目的とした投稿は推奨していません。 「編集」ボタンから編集を行い、質問の意図や解決したい課題を明確に記述していただくと回答が得られやすくなります。
guest

回答1

0

ベストアンサー

単純にデータベースの更新処理を全て終えた後にビューの描画を行いたいということでしょうか?

それであれば、doc.saveの引数に渡している無名関数の最後で、
ビューの描画処理を行えば良いと思います。

ただし、全ての処理を終えた後にのみビューの描画処理が実行されるように、
何件処理が終わったかのカウントはとっておく必要があると思います。

以下のサイトの上から3つ目のコードが参考になると思います。(最初の1つ目と2つ目のコードは間違ったやり方を示すサンプルコードです)
http://mostafa-samir.github.io/async-iterative-patterns-pt1/

投稿2016/02/02 08:07

編集2016/02/02 08:11
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

terry-0121

2016/02/03 16:57

回答をいただきありがとうございます。 何件処理が終わったかのカウントを取ればいいということですね。 ちょっとやってみます。 できたらまたご連絡いたします。
terry-0121

2016/02/18 17:00

うまくできました。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問