1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

MongoDB Oracleのdual表と同じようにダミーCollectionを作って活用しよう

Posted at

概要

Oracleのdual表と同じようにダミーCollectionを作るとAggregationのいろいろなテストが出来る。

ダミーCollectionの作成

データベース名はdummyでCollectionをdualとする

dualのデータを作成する

> use dummy
switched to db dummy
> db.dual.insert({_id:1})
WriteResult({ "nInserted" : 1 })
> db.dual.find()
{ "_id" : 1 }
>

dualを使った例

データが1件で良い場合

$indexOfArrayのテスト

db.getSiblingDB("dummy").dual.aggregate([
    {$project:{
        idx1:{$indexOfArray:[[1,2,3,4],3]},
        idx2:{$indexOfArray:[[1,2,3,4],5]}
    }}
])
{ "_id" : 1, "idx1" : 2, "idx2" : -1 }

上記の**$indexOfArray**をフィールド名を使った例にする。

db.getSiblingDB("dummy").dual.aggregate([
    {$project:{
       array:[1,2,3,4],
       idx1: {$literal: 3}
    }},
    {$project:{
        idx1:{$indexOfArray:["$array","$idx1"]},
        idx2:{$indexOfArray:["$array",5]}
    }}
])
{ "_id" : 1, "idx1" : 2, "idx2" : -1 }

上記での注意点はidx1: {$literal: 3}idx1:3としないことです

データが複数件必要な場合

$groupの例

ここで問題になるのが、dualは1件しかないので**$group**は難しいです。まずは複数のデータ作成するところから考えます。

db.getSiblingDB("dummy").dual.aggregate([
    {$project:{
      _id: 0,
      idx:[0,1,2,3],
      data:[[2, -1], [1, 20], [2, 1], [1, 10]]
    }}, 
    {$unwind: "$idx"},
    {$project:{
      key: {$arrayElemAt:[{$arrayElemAt:["$data", "$idx"]}, 0]},
      num: {$arrayElemAt:[{$arrayElemAt:["$data", "$idx"]}, 1]}
    }}
])
{ "key" : 2, "num" : -1 }
{ "key" : 1, "num" : 20 }
{ "key" : 2, "num" : 1 }
{ "key" : 1, "num" : 10 }

idxdata の添え字を表し、datakeynumの配列[[key0,num0],[key1,num1],...]になっています。その後の$unwindで複数ドキュメントを作成して$projectで整形します。

このデータを使って$groupを実行します。

db.getSiblingDB("dummy").dual.aggregate([
    {$project:{
      _id: 0,
      idx:[0,1,2,3],
      data:[[2, -1], [1, 20], [2, 1], [1, 10]]
    }}, 
    {$unwind: "$idx"},
    {$project:{
      key: {$arrayElemAt:[{$arrayElemAt:["$data", "$idx"]}, 0]},
      num: {$arrayElemAt:[{$arrayElemAt:["$data", "$idx"]}, 1]}
    }},
    {$group:{
        _id:"$key", sum:{$sum:"$num"}
    }}
])
{ "_id" : 2, "sum" : 0 }
{ "_id" : 1, "sum" : 30 }

NumberDecimalの四則演算に活用

mongo shellでNumberDecimalの演算方法が見つかりませんでしたので自分で作ってみます。例は加算(add)のみ記載します。以下を.mongorc.jsに記述します。

.mongorc.js
NumberDecimal.prototype.add = function(other) {
  let result = db.getSiblingDB("dummy").dual.aggregate([
     {$project:{
      result:{$add:[this, other]}, _id: 0
     }}
  ]).toArray()
  return result[0].result
}

演算例

> num=NumberDecimal("123456789012345678901234567890")
NumberDecimal("123456789012345678901234567890")
> num.add(NumberDecimal("1"))
NumberDecimal("123456789012345678901234567891")

終わりに

死活の確認のためにpingコマンドの代わりにdualfindで対応することも可能です。用途はほぼOracle同様の使い方と同じです。
問題があるとすれば、$lookup$graphLookupには使えないことです。これらは複数のドキュメントを持っているCollectionが必要になります。別途dual以外のCollectionを作れば対応可能です。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?