2

基本的に、コレクション内のドキュメントをカウントし、新しいドキュメントを _id として設定しようとしています。いくつかの組み合わせを試しましたが、どれもうまくいかないようです。

これが私が試したことです:

var count = PostModel.find( function( err, posts ) {
    if ( !err ) {
        return posts.length;
    }
    else {
        return console.log( err );
    }
});

var post = new PostModel({
    _id: count,
    title: request.body.title,
    content: request.body.content,
    tags: request.body.tags
});

戻り値:

{ message: 'Cast to number failed for value "[object Object]" at path "_id"',
  name: 'CastError',
  type: 'number',
  value:
   { options: { populate: {} },
     safe: undefined,
     _conditions: {},
     _updateArg: {},
     _fields: undefined,
     op: 'find',
     model:
      { [Function: model]
        modelName: 'Post',
        model: [Function: model],
        options: undefined,
        db: [Object],
        schema: [Object],
        collection: [Object],
        base: [Object] } },
  path: '_id' }

この:

var post = new PostModel({
    _id: PostModel.find( function( err, posts ) {
        if ( !err ) {
            return posts.length;
        }
        else {
            return console.log( err );
        }
    }),
    title: request.body.title,
    content: request.body.content,
    tags: request.body.tags
});

同じエラーを返します。ただし、次を個別に追加すると、コレクションの長さが記録されます。

PostModel.find( function( err, posts ) {
    if ( !err ) {
        return console.log(posts.length);
    }
    else {
        return console.log( err );
    }
});

私も色々と使ってみcount()ましたが、上手くいきませんでした。カウントのコレクションをクエリし、それを _id として設定する方法についての洞察は非常に役立ちます。

4

1 に答える 1

2

まず第一に、これはうまくスケーリングできないため、MongoBDでは推奨されません。

しかし、本当にやりたい場合は、MongoDB の公式ドキュメントに適切で安全な方法の説明があります

基本的に、小さなドキュメントを使用して現在のシーケンス ID を保持し、ドキュメントを挿入するたびに、そのシーケンスをアトミックに読み取り、インクリメントします。挿入するたびにドキュメントをカウントするよりもはるかに効率的です。

あなたのソリューションでは、2 つのプロセスが同時に実行されているとどうなりますか? 挿入とシーケンスの生成/カウントはアトミックではないため、同一の ID になる可能性があります。

編集:

モデルからカウントを取得するには、次を使用します。

PostModel.count( function (err, count) {
  if (err) ..
  console.log('there are %d posts', count);
});

OPによる編集:

以下のコメントによると、問題は非同期関数を同期的に使用することにありました。すべてのコードをコールバック関数に移動すると、機能しました。解決策は次のとおりです。

PostModel.count( function (err, count) {
    if (err)
        console.log(err);
    else {
        console.log('there are %d posts', count);

        var post = new PostModel({
            _id: count,
            title: request.body.title,
            content: request.body.content,
            tags: request.body.tags
        });

        post.save( function( err ) {
            if( !err ) {
                return console.log( 'Post saved');
            } else {
                console.log( err );
            }
        });

        return response.send(post);
    }
});
于 2013-11-04T03:25:42.223 に答える