よく使うmongoDBクエリ

# 概要

ほぼ自分用mongoDBの検索クエリのスニペットです。

# Snippets

## 不要なデータを切り捨てて取得

特定のフィールドだけ取得したい場合`fieldName: 1`を指定する

```js
db.collection.aggregate([
  {
    $project: {
      _id: 0, // _idを非表示にするには明示的に_id:0 を書く
      fileldName: 1 // 表示したいフィールド
    }
  }
])
```

[playground](https://mongoplayground.net/p/r1gKlMBqxtC)

もしくは特定のフィールド以外を取得したいときは非表示にしたいフィールドに`fieldName: 0`を指定する

```js
db.collection.aggregate([
  {
    $project: {
      _id: 0, // _idを非表示にするには明示的に_id:0 を書く
      fileldName: 0 // 非表示したいフィールド
    }
  }
])
```

[playground](https://mongoplayground.net/p/irkVmos2Fzh)


## 配列を展開して取得

1ドキュメント中に配列長が3のデータがあったとしたら、
3ドキュメント、配列はそれぞれ展開した状態で取得します。

```js
db.collection.aggregate([
    {$unwind : "$arrayFieldName"}
]);
```

[playground](https://mongoplayground.net/p/1V1_WNRb3Ha)

## コレクションを結合して取得

```js
db.localCollection.aggregate([
  {
    $lookup: {
      from: "otherCollectionName", // 結合コレクション名
      localField: "localCollectionFieldName", 結合元コレクションキーフィールド名
      foreignField: "otherCollectionFieldName", // 結合コレクションキーフィールド名
      as: "outArrayFieldName"  // 結合結果配列フィールド名
    }
  },
])
```

[playground](https://mongoplayground.net/p/ZvpamHoTTcB)

## 秒を時分秒変換して取得

あんまり使わないかも・・・
クエリで処理せず、プログラム側で変換するほうが効率よく変換できそうですが、クエリだけで視認しやすいデータを取得したいときに使うかも程度

<details><summary>クエリ</summary><div>

```js
db.collection.aggregate([
  {
    $project: {
      // 一旦秒を時分秒に変換する
      name: 1,
      fieldName_hour: {
        $floor: {
          $divide: [
            "$fieldName",
            3600
          ]
        },
      },
      fieldName_min: {
        $floor: {
          $mod: [
            {
              $divide: [
                "$fieldName",
                60
              ]
            },
            60
          ]
        },
      },
      fieldName_sec: {
        $floor: {
          $mod: [
            "$fieldName",
            60
          ]
        },
      },
    }
  },
  {
    // 符号の付与
    $project: {
      name: 1,
      fieldName: {
        $concat: [
          {
            $cond: {
              if: {
                $lt: [
                  "$fieldName_hour",
                  10
                ]
              },
              then: {
                $concat: [
                  "0",
                  {
                    $toString: "$fieldName_hour"
                  }
                ]
              },
              else: {
                $toString: "$fieldName_hour"
              }
            }
          },
          ":",
          {
            $cond: {
              if: {
                $lt: [
                  "$fieldName_min",
                  10
                ]
              },
              then: {
                $concat: [
                  "0",
                  {
                    $toString: "$fieldName_min"
                  }
                ]
              },
              else: {
                $toString: "$fieldName_min"
              }
            }
          },
          ":",
          {
            $cond: {
              if: {
                $lt: [
                  "$fieldName_sec",
                  10
                ]
              },
              then: {
                $concat: [
                  "0",
                  {
                    $toString: "$fieldName_sec"
                  }
                ]
              },
              else: {
                $toString: "$fieldName_sec"
              }
            }
          }
        ]
      },
    }
  }
])
```

1回目の`$project`で秒を時分秒に変換後、2回目の`$project`で符号の付与を行っています。
(クエリだけでやっているため、`$concat`を使用するために数値から文字列に変換、ゼロパディングを行う等回りくどい気もする。。。
他にやり方ご存じの方いらっしゃいましたらコメント頂けると助かります。)

</div></details>

[playground](https://mongoplayground.net/p/XW1oFeTrJUT)


# 終わりに

他によく使うクエリがあれば追記していこうと思います。