0

私はチャットアプリケーションに取り組んでおり、会話の各イベントには送信者という名前のフィールドがあります-次のようになります:

var eventSchema = Schema({
    sender: {
        type: {}, //username && user_id fields
        required: true
    }
}

Event が作成されるたびに、sender フィールドに次のようなオブジェクトを渡します。

{
    username: String,
    user_id: ObjectId("")
}

Event.sender の user_id フィールドが毎回 ObjectId 型であることは確かです。

ただし、データベースでは、保存されたイベントに String && 型の Event.sender.user_id が含まれる場合があり、ObjectId() 型として保存された Event.sender.user_id が含まれることがあります。

{
    username: String,
    user_id: ObjectId("")    // sometimes it saves like this
}

{
    username: String,
    user_id: String    // other times it saves like this
}

変化はかなり頻繁に発生し、同じユーザーによって送信されたイベントがあり、この変化を示す 10 分間の時間枠内で同じコントローラー関数を通過します。

スキーマの混合型フィールド内での ObjectIds の保存方法に影響する、説明していない Mongoose の特定の動作はありますか?

この動作は、更新ではなく、保存時に発生します。システム内の Event.sender フィールドに対して行われる更新はありません。

4

1 に答える 1

1

その答えは、開発環境で私たちから隠されているという点で、かなりあいまいでした。この問題は、Node プロセスがクラスター化されている場合にのみ発生します。これは実際には本番環境でのみ見られます。Mongoose に user_id の文字列化されたバージョンを渡していたことが判明したため、問題は Redis ストア メカニズムがどのように機能するかを理解していないことにありました。

本番環境では、redis ストアを使用して、socket.io の Node プロセス全体でセッションを管理します。そのため、ハンドシェイクの途中で、最初にハンドシェイクを開始したプロセスとは異なるプロセスに HTTP リクエストが到達する可能性があります。その後、Redis Store はハンドシェイク オブジェクトを文字列化し、実行中の他のすべてのプロセスに送信します。

その stringify のために、アプリケーション内の多くの場所で使用する user_id の ObjectId ラッパーが失われ、多くのイベントの送信者オブジェクト内に文字列を保存することになります。

これが誰かの助けになることを願っています。

于 2014-11-22T18:14:51.073 に答える