sql >> データベース >  >> NoSQL >> MongoDB

MongoDBに文字列形式で保存された日時フィールドの日時の差を計算する必要があります

    すべてのステージを作成しましたが、ここで重要なのは、相互に関係がないことです。つまり、前のセットアップで行われた変更は、次のステップに反映されていません。いくつかの問題:

    {$sort: {$dateFromString:{time: 1}}} // You can't use `$dateFromString` in sort stage. Also syntax of `$dateFromString` is incorrect.
    

    それが機能した場合(機能しないと仮定します)、実際にはtimeを変換していないと仮定しましょう。 &変換された時間を変数に保存して、後で$groupで使用できるようにします またはさらにダウンステージ。したがって、$addFieldsを使用して、それぞれのドキュメントの変数に保存する必要があります。 または$project 。私はさらに下に行きませんでしたが、以下のクエリを試すことができます:

    クエリ:

    db.collection.aggregate([
        /** sort on `time` field */
        { $sort: { time: 1 } },
        /** Convert string format of `time` field to milliseconds & store to `convertedTime` field for each doc */
        { $addFields: { convertedTime: { $toLong: { $dateFromString: { dateString: "$time" } } } } },
        /** Group without condition to push all documents into `docs` array */
        {
          $group: { _id: "", docs: { $push: "$$ROOT" } }
        },
        /** re-creating `docs` array */
        {
          $project: {
            _id: 0,
            docs: {
              $reduce: {
                input: { $slice: [ "$docs", 1, { $size: "$docs" } ] }, /** Pick `docs` array without first element for iteration */
                initialValue: {  docObj: [ { $arrayElemAt: [ "$docs", 0 ] } ], previousTime: { $arrayElemAt: [ "$docs.convertedTime", 0 ] } },
                in: {
                  docObj: { $concatArrays: [ "$$value.docObj", [
                        { $mergeObjects: [ "$$this", { time_difference: { $divide: [ { $subtract: [ "$$this.convertedTime", "$$value.previousTime" ] }, 1000 ] } } ] }
                      ]
                    ]
                  },
                  previousTime: "$$this.convertedTime" // Store current doc's time to `previousTime` to utilize for next record
                }
              }
            }
          }
        },
        {
          $unwind: { path: "$docs.docObj" }
        },
        /** Remove additionally added field */
        {
          $project: { "docs.docObj.convertedTime": 0 }
        },
        /** Replace root of the doc with `docs.docObj` */
        {
          $replaceRoot: { newRoot: "$docs.docObj" }
        }
      ])
    

    テスト: mongoplayground

    参照: Aggregation-pipeline

    注: このクエリは"time_difference" :nullを追加しません 最初のドキュメントの場合ですが、必要な場合に備えて、initialValueでこれを試してください。 :docObj: [ {$mergeObjects :[ { $arrayElemAt: [ "$docs", 0 ] }, { "time_difference" :null } ] ] 。また、$matchを使用して、この操作をコレクション内の特定のドキュメントに制限することをお勧めします。 最初の段階として、すべてのドキュメントに対してこのクエリを実行するのではなく、

    {
       $group: { _id: "", docs: { $push: "$$ROOT" } }
    }
    

    巨大なデータセットを使用してコレクション全体で実行すると、それ自体が大きなものになります。




    1. プロシージャはmongodbに存在します

    2. mongodb$existsは常に0を返します

    3. ルートとして実行しない限り、mongodの起動は失敗します

    4. Mongodbで月と年の範囲でフィルタリングする方法