MongoDB

MongoDB ログイン

ローカルホストへのMongoDBへのログイン

# mongo [DB名]  -u 「UserのDB名」 -p

I.E

# mongo mango_db_name  -u username -p

MongoDB shell version v3.6.10
Enter password:
connecting to: mongodb://127.0.0.1:27017/mango_db_nameb?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("a384d33f-ec64-4c87-b6f6-77503e6ad3df") }
MongoDB server version: 3.6.10

リモートホストのMongoDBへのログイン

$ mongo  --host「ホスト名」 -u 「ユーザー名」   -p [password]    [DB名]
I.E

$ mongo --host 192.167.8.29:27000 -u mongo -p password_name  database_name
MongoDB shell version v3.6.18
connecting to: mongodb://xxxxxxxxx
Implicit session: session { "id" : UUID("3b058d16-2e6a-4fab-bbac-35abb5a785c9") }
MongoDB server version: 4.4.3
WARNING: shell and server versions do not match
> show dbs
database_name  0.024GB

もしくは、

$ mongo  mongodb://「ユーザー名」:「パスワード」@「IP」:「ポート」/「DB名」

I.E

$ mongo mongodb://Username:MongoPassword@192.168.1.5:27017/database_mongo_name
MongoDB shell version v4.4.

*ただし、デフォルトでは、リモートからのアクセスは、禁止されているため許可する必要がある。
/etc/monod.conf`のbindIpに、接続元のIPを入力する。

# network interfaces
net:
  port: 27017
  bindIp: 127.0.0.1,10.192.168.1.1,10.165.8.100

その後、サービスを再起動する。

systemctl restart mongod.service

*認証をDisabledにする方法もある。 /etc/monod.conf のsecurity configをコメントアウトして、再起動すると、認証が不要になる。 どうしても、アクセスできないようであれば、一時的にこちらの方法を利用してもよいだろう。

認証を有効にしている場合、データベースごとにユーザー・passが必要になる。 そのため、ログイン時に以下のように、データベースを指定したうえで、ログインする必要がある。 指定しないと、ログインできたように見えるが、show dbsの結果が出ないなどの問題にあたるかも

$ mongo --host 192.167.8.29:27000 -u mongo -p passwork_name  database_name
# security config
# BEGIN ANSIBLE MANAGED BLOCK
security:
  keyFile: /etc/mongo_key
  authorization: enabled

また、データベースごとに、アクセス可能なユーザーが定義されています。 特定のデータベースにアクセスするためには、アクセス権を持っているアカウントでのアクセスが必要となります。 ユーザの作成には、”ユーザー作成”を参照ください。

MongoDB操作

DB作成 or DBの切り替え

use 「DB名」;

I.E mongo_db_nameという名称のmongoDBを作成する or DBを切り替える場合

> use mongo_db_name
switched to db mongo_db_name

DB一覧参照

show dbs;

I.E DBの一覧参照

> show dbs;
admin                                      0.000GB
config                                     0.000GB
local                                      0.000GB
alert_db          37.617GB
compabt_db            0.075GB

Collection 操作

Collectoin一覧参照

> show collections
collection1
collecton2

ドキュメント操作

ドキュメント一覧参照

db.<ドキュメント名>.find()
I.E
db.collection1.find()

ドキュメント検索 find()を利用

ドキュメントのKey,Valueで検索
db.<コレクション名>.find( { key: value} )

例えば、コレクション名がcollection1, 検索したいkeyがType, valueがcatの場合

db.collecton1.find( { Type:  "cat"} )

なお、And検索は、以下の通り。

db.<コレクション名>.find( { key: value, key2: value2 } )
 ワイルドカードで検索。

ワイルドカードの検索は、$regexを利用する。 KeyがType、Valueにcatが含まれているドキュメントを検索する。

db.collection1.find({Type : {$regex : "cat" } })
最新のドキュメントから5件を出力(idが最新のドキュメントを検索)
db.<コレクション名>.find().sort({_id: -1}).limit(5)

ドキュメント名がcollection1から最新の5件を検索。

db.collection1.find().sort({_id: -1}).limit(5)
ドキュメントの検索結果を見やすくする(成形された結果を出力)

検索コマンドの最後に.pretty()を追加することで、成形された結果が出てくる。

db.<コレクション名>.find().sort({_id: -1}).limit(5).pretty()

*注意点として、外部からmongoにアクセスする場合、以下のように、find内の検索クエリの”をエスケープする必要がある。 mongo --host 192.168.10.25:27010 --eval "db.collection1.find({Type : \"cat\"})" database_name -u mongo_user -p mongo_pass

特定のフィールドのみを出力する

例えば、出力結果がJson形式でいかのようになっていたとします。

{
   "id" :{
      "date": {
          "name": "A-san
       }   
   }
}

nameフィールドのみを取り出したい場合は、以下のようにします。

db.alerts.find({} , {'id.date.name':1})
日付で検索(特定の日時より新しい日付で検索)

TimeStampが、2021-01-05T10:50:19より新しい場合。

db.<コレクション名>.find({ timestamp : { "$gt":  ISODate('2021-01-05T10:50:19')}})

xx以上の場合は$gte xxより大きい場合は、$gt xx以下の場合は、$lte xx寄居小さい場合は、$lt

ドキュメントのデータを集計(加算する) aggregate()を利用

aggregateの基本的な使い方
db.コレクション名.aggregate([{$match: {検索条件}, {$group: {集計条件}}}] 
$matchは検索条件、$groupは集計の条件
$matchに関しては省略が可能

例えば、以下のようにtype、 timestamp , countからなるデータが保存されていたとします。

{ "type" : "Atype",  "timestamp" : ISODate("2022-01-01T07:02:29Z"),  "count" : 4},
{ "type" : "Btype",  "timestamp" : ISODate("2022-01-14T02:42:33Z"),  "count" : 13),
{ "type" : "Btype",  "timestamp" : ISODate("2022-01-12T12:32:29Z"),  "count" : 34}、
{ "type" : "Ctype",  "timestamp" : ISODate("2022-01-12T12:32:29Z"),  "count" : 34}

ここから、typeがBtypeのもので、かつ、timestampが2022-01-12T00:00:00+09:00以降のものだけ検索し、そのcountを加算するような操作は、以下のようなqueryになります。

db.alerts.aggregate(   {$match: {Type: "Btype", timestamp: {$gt: ISODate("2022-01-12T00:00:00+09:00")  } }  } ,  { $group:  { _id: "$Type", total:  { $sum: "$count" } } }      )

まず、$matchで検索条件を指定します。 次に、Typeのフィールドでグルーピングします。$groupの_id で指定されてる値がグルーピングする対象です。 そして、$sumで、countフィールドの値を加算します。 結果は以下のようになるはずです。

{ "_id" : "Btype", "total" : 47 }

ドキュメントの任意のデータを出力する $projectを利用

projectの基本的な使い方

aggregate()内で利用して、任意のデータフィールドを表示させます。SQLのselect col1, col2, col3 from DB; のようなイメージです。

例えば、以下のようなデータがあったとします。

{ "Type": "ABCDtype", "timestamp" : ISODate("2022-01-24T01:46:01Z"), "total" : 1 , "count" : 12 }
{ "Type": "ABCDtype", "timestamp" : ISODate("2022-05-22T11:36:02Z"), "total" : 1 , "count" : 12 }
{ "Type": "CDtype", "timestamp" : ISODate("2022-09-12T09:49:02Z"), "total" : 1 , "count" : 12 }
{ "Type": "Dtype", "timestamp" : ISODate("2022-12-24T03:41:141Z"), "total" : 1 , "count" : 12 }

以下のQueryは次のように動きます。

db.data.aggregate(   {$match: {Type: "ABCDtype" }  {$project: { "timestamp": 1,  total: "$total" ,  count: "$count" ,  result : {"$divide" : ["$total", "$count"]} } } )
  1. $matchでTypeがABCDtypeのデータを選択します。
  2. そのなかから、$projectで出力したい、データを選択します。この場合は、timestamp, total, count, resultが出力されます。  timestamp:1とすることで、データが出力され、表示したくないときは、timestamp:0とします。  また、resultのフィールドは、新規に追加しています。resultの中身は、各データの$totalを$countで割った(divide)値を表示します。

このように任意の結果を$projectで加工して、表示できます。

mongodb外部からの操作

以下のように、 --evalコマンドを利用して、Mongo外から操作ができる。 ただし、外部から、コマンドを実行できるように設定を事前に実施する必要がある。 ”リモートホストのMongoDBへのログイン”を参照のこと。

mongo --host 192.168.10.2:27012 --eval "db.collection1.find().sort({_id: 1}).limit(1)"  mongo_db_name-u mongo_user -p mongo_password

*注意点として、Queryで(とくにfind()で)ダブルクウォテーション”やシングルクウォテーションが利用されるが、escapeしないと、うまく検索できない場合がある。

コレクションデータの全件削除

db.コレクション名.remove({});

表示するコレクションの上限の設定を変更する

find()などで検索した結果の出力上限は20に設定されています。 これを変更するには、以下のようにします。出力上限が40になります。

DBQuery.shellBatchSize = 40

Mongo DBの障害調査

Mongoの設定ファイル

Mongの設定ファイルは通常以下に保存される。

 /etc/mongod.conf

また、Mongのデータ保存バスは設定ファイル(mongod.conf)の”Strage:”で設定される。

#cat /etc/mongod.conf

# Where and how to store data.
storage:
  dbPath: /var/lib/mongodb
  journal:
    enabled: true

mongodが起動しない場合、上記のdbPath先がなく、デーモンが起動しない場合があるので、パスの確認が必要。

データ容量を調べる db.status()

db.status()でデータサイズを調べることができます。。 dataサイズあたりを見ればよいです。

> db.stats()
{
        "db" : "pulse_database_alerts_alert",
        "collections" : 2,
        "views" : 0,
        "objects" : 477256,
        "avgObjSize" : 363.51303074241076,
        "dataSize" : 173488775,
        "storageSize" : 164175302656,
        "indexes" : 5,
        "indexSize" : 41529344,
        "totalSize" : 164216832000,
        "scaleFactor" : 1,
        "fsUsedSize" : 380248883200,
        "fsTotalSize" : 386358312960,
        "ok" : 1
}

ユーザー関連

ユーザー一覧表示

db.system.users.find()

ユーザ作成

ユーザは基本的に、データベースごとに作成します。データベースごとに作成されたユーザがそのデータベースへのアクセス権が付与されます。 ただし、adminデータベースで作成したユーザは、管理者となれます。

//データベースへの切り替え
# use ”データベース名”


// 特定のデータベースのみ管理者権限をもつユーザの作成

> db.createUser(
  {
    user: "ユーザ名",
    pwd: "パスワード",
    roles:
    [
      {
        role: "userAdmin",
        db: "データベース名"
      }
    ]
  }
)