「MongoDBをDocker上に構築してみる」で MongDBの環境を作成したので、データの検索について試してみたいと思います。
初期データ
上記で初期データとして投入したものでは少し物足りないので、初期データを下記のものに入れ替えました。自分がRDBの考え方になっているので、リレーション風のデータの形で、投入してみます。
db = db.getSiblingDB('db_employee_info');
db.employee.insertMany([
{
employeeID: 'emp001',
divisionID: 'ka001',
roleID: 'yaku001',
employeeName: '田村',
age: 30,
salary: 400000,
created_date: new Date(),
updated_date: new Date()
},
{
employeeID: 'emp002',
divisionID: 'ka001',
roleID: 'yaku002',
employeeName: '山田',
age: 31,
salary: 350000,
created_date: new Date(),
updated_date: new Date()
},
{
employeeID: 'emp003',
divisionID: 'ka002',
roleID: 'yaku003',
employeeName: '中山',
age: 37,
salary: 300000,
created_date: new Date(),
updated_date: new Date()
},
{
employeeID: 'emp004',
divisionID: 'ka002',
roleID: 'yaku004',
employeeName: '佐藤',
age: 23,
salary: 250000,
created_date: new Date(),
updated_date: new Date()
},
{
employeeID: 'emp005',
divisionID: 'ka003',
roleID: 'yaku002',
employeeName: '佐々木',
age: 33,
salary: 350000,
created_date: new Date(),
updated_date: new Date()
},
{
employeeID: 'emp006',
divisionID: 'ka004',
roleID: 'yaku002',
employeeName: '吉田',
age: 35,
salary: 350000,
created_date: new Date(),
updated_date: new Date()
}
]);
MongoDBが起動されたら、NoSQL Booster で確認したところ、初期データが登録されていることが確認できました。
データベース用語の違い
MongoDBはスキーマレスであれことから、データベースで使用される用語が違います。MongoDBとRBDの違いを記しておきます。
RDB | MongoDB |
---|---|
テーブル | コレクション |
行 | ドキュメント |
列 | フィールド |
プライマリキー | ObjectID |
インデックス | インデックス |
検索
> db.collection.find(
{ <検索条件> },
{ key1: 0, key2: 1, ・・・}
)
最初の{ }は検索条件を指定します。検索条件はJSONのような形式で記述します。
その後に、指定したフィールドだけを取得します。
key: 0 フィールドを非表示にする
key: 1 フィールドを表示する
> db_employee_info> db.employee.find({age:31})
[
{
_id: ObjectId('668b87b9e98d52fe42f3f54f'),
employeeID: 'emp002',
divisionID: 'ka001',
roleID: 'yaku002',
employeeName: '山田',
age: 31,
salary: 350000,
created_date: ISODate('2024-07-08T06:31:21.820Z'),
updated_date: ISODate('2024-07-08T06:31:21.820Z')
}
]
> db_employee_info> db.employee.find({age:31},{_id:0, age:0})
[
{
employeeID: 'emp002',
divisionID: 'ka001',
roleID: 'yaku002',
employeeName: '山田',
salary: 350000,
created_date: ISODate('2024-07-08T06:31:21.820Z'),
updated_date: ISODate('2024-07-08T06:31:21.820Z')
}
]
> db_employee_info> db.employee.find({age:31},{employeeName:1})
[
{
_id: ObjectId('668b87b9e98d52fe42f3f54f'),
employeeName: '山田'
}
]
『_id』は、データを登録したときに自動で付与される主キーになります。
配列データ
MongoDBでは、配列のデータを保持することができます。
db.employee.insertOne({
employeeID: 'emp008',
divisionID: 'ka001',
roleID: 'yaku004',
employeeName: '大田',
age: 36,
salary: 320000,
skill: [ { name: "Oracle", level: 3},{ name: "MySQL", level: 2},{ name: "Redis", level: 1},{ name: "MongoDB", level: 5}],
created_date: new Date(),
updated_date: new Date()
})
> db.employee.find({"skill.level":3},{_id:0})
[
{
employeeID: 'emp008',
divisionID: 'ka001',
roleID: 'yaku004',
employeeName: '大田',
age: 36,
salary: 320000,
skill: [
{ name: 'Oracle', level: 3 },
{ name: 'MySQL', level: 2 },
{ name: 'Redis', level: 1 },
{ name: 'MongoDB', level: 5 }
],
created_date: ISODate('2024-07-08T09:09:51.607Z'),
updated_date: ISODate('2024-07-08T09:09:51.607Z')
}
]
配列の中のオブジェクトを検索条件に指定する場合は『"配列.オブジェクトのプロパティ名"』を指定します。この場合、""(ダブルコーテーション)で括る必要があります。上記では、"skill.level" としています。
検索条件(完全一致/部分一致/前方一致/後方一致)
> db_employee_info> db.employee.find( { employeeName: '山田' },{ _id:0 } )
[
{
employeeID: 'emp002',
divisionID: 'ka001',
roleID: 'yaku002',
employeeName: '山田',
age: 31,
salary: 350000,
created_date: ISODate('2024-07-08T06:31:21.820Z'),
updated_date: ISODate('2024-07-08T06:31:21.820Z')
}
]
> db_employee_info> db.employee.find( { employeeName: /田/ },{ employeeName:1 } )
[
{ _id: ObjectId('668b87b9e98d52fe42f3f54e'), employeeName: '田村' },
{ _id: ObjectId('668b87b9e98d52fe42f3f54f'), employeeName: '山田' },
{ _id: ObjectId('668b87b9e98d52fe42f3f553'), employeeName: '吉田' },
{ _id: ObjectId('668bacdf05dbdfe7c7f3f54f'), employeeName: '大田' }
]
> db_employee_info> db.employee.find( { employeeName: /^田/ },{ employeeName:1 } )
[ { _id: ObjectId('668b87b9e98d52fe42f3f54e'), employeeName: '田村' } ]
> db_employee_info> db.employee.find( { employeeName: /田$/ },{ employeeName:1 } )
[
{ _id: ObjectId('668b87b9e98d52fe42f3f54f'), employeeName: '山田' },
{ _id: ObjectId('668b87b9e98d52fe42f3f553'), employeeName: '吉田' },
{ _id: ObjectId('668bacdf05dbdfe7c7f3f54f'), employeeName: '大田' }
]
検索条件(範囲指定)
> db_employee_info> db.employee.find({age: { $lte: 30 } },{ employeeName:1, age:1 } )
[
{
_id: ObjectId('668b87b9e98d52fe42f3f54e'),
employeeName: '田村',
age: 30
},
{
_id: ObjectId('668b87b9e98d52fe42f3f551'),
employeeName: '佐藤',
age: 23
}
]
> db_employee_info> db.employee.find({age: { $lt: 30 } },{ employeeName:1, age:1 } )
[
{
_id: ObjectId('668b87b9e98d52fe42f3f551'),
employeeName: '佐藤',
age: 23
}
]
> db_employee_info> db.employee.find( { age: { $gte: 36 } },{ employeeName:1, age:1 } )
[
{
_id: ObjectId('668b87b9e98d52fe42f3f550'),
employeeName: '中山',
age: 37
},
{
_id: ObjectId('668babfb05dbdfe7c7f3f54e'),
employeeName: '上野',
age: 36
},
{
_id: ObjectId('668bacdf05dbdfe7c7f3f54f'),
employeeName: '大田',
age: 36
}
]
> db_employee_info> db.employee.find( { age: { $gt: 36 } },{ employeeName:1, age:1 } )
[
{
_id: ObjectId('668b87b9e98d52fe42f3f550'),
employeeName: '中山',
age: 37
}
]
> db_employee_info> db.employee.find(
{ age: { $gte: 30, $lte: 32 } },
{ employeeName:1, age:1 }
)
[
{
_id: ObjectId('668b87b9e98d52fe42f3f54e'),
employeeName: '田村',
age: 30
},
{
_id: ObjectId('668b87b9e98d52fe42f3f54f'),
employeeName: '山田',
age: 31
}
]
db_employee_info> db.employee.find(
{ $and: [
{ employeeName: /田/ },
{age: {$lte: 32 } }
] },
{ employeeName:1, age:1 }
)
[
{
_id: ObjectId('668b87b9e98d52fe42f3f54e'),
employeeName: '田村',
age: 30
},
{
_id: ObjectId('668b87b9e98d52fe42f3f54f'),
employeeName: '山田',
age: 31
}
]
> db_employee_info> db.employee.find(
{ $or: [
{ employeeName: /田村/ },
{ age: { $gte: 37 } }
] },
{ employeeName:1, age:1 }
)
[
{
_id: ObjectId('668b87b9e98d52fe42f3f54e'),
employeeName: '田村',
age: 30
},
{
_id: ObjectId('668b87b9e98d52fe42f3f550'),
employeeName: '中山',
age: 37
}
]
> db_employee_info> db.employee.find({"skill.name": {$exists: true}},{employeeName:1, skill:1})
[
{
_id: ObjectId('668bacdf05dbdfe7c7f3f54f'),
employeeName: '大田',
skill: [
{ name: 'Oracle', level: 3 },
{ name: 'MySQL', level: 2 },
{ name: 'Redis', level: 1 },
{ name: 'MongoDB', level: 5 }
]
}
]
> db_employee_info> db.employee.find({skill: {$size: 4}},{employeeName:1, skill:1})
[
{
_id: ObjectId('668babfb05dbdfe7c7f3f54e'),
employeeName: '上野',
skill: [ 'Oracle', 'MySQL', 'Redis', 'MongoDB' ]
},
{
_id: ObjectId('668bacdf05dbdfe7c7f3f54f'),
employeeName: '大田',
skill: [
{ name: 'Oracle', level: 3 },
{ name: 'MySQL', level: 2 },
{ name: 'Redis', level: 1 },
{ name: 'MongoDB', level: 5 }
]
}
]
> db_employee_info> db.employee.find(
{},
{ _id: 0, employeeName: 1, age: 1 }
).sort(
{ age: 1 }
)
[
{ employeeName: '佐藤', age: 23 },
{ employeeName: '田村', age: 30 },
{ employeeName: '山田', age: 31 },
{ employeeName: '佐々木', age: 33 },
{ employeeName: '吉田', age: 35 },
{ employeeName: '上野', age: 36 },
{ employeeName: '大田', age: 36 },
{ employeeName: '中山', age: 37 }
]
> db_employee_info> db.employee.find(
{},
{ _id: 0, employeeName: 1, age: 1 }
).sort(
{ age: 1 }
).limit(2)
[
{ employeeName: '佐藤', age: 23 },
{ employeeName: '田村', age: 30 }
]
> db_employee_info> db.employee.find(
{},
{ _id: 0, employeeName: 1, age: 1 }
).sort(
{ age: 1 }
).limit(2).skip(2)
[
{ employeeName: '山田', age: 31 },
{ employeeName: '佐々木', age: 33 }
]
最後に
今回はここまでとします。RDBのSQLと違い、JSON形式のデータを検索する機能(要素数による検索、フィールド名による検索)が用意されているため、RDBとはまた違った活用方法があると感じました。
他にも色々な検索条件があるようなので、便利な検索条件があればコメントいただけるとうれしいです。