mongdb データベースは、主にデータ構造のストレージとクエリ構文の点で、リレーショナル データベースとはまったく異なります。Mongdb は、bson 形式のデータ (json 形式に類似) であるドキュメントにデータを保存し、mongdb の JavaScript 構文を使用して修飾されたドキュメントのコンテンツをフェッチおよび読み取り、テーブルの形式で表示します。クエリ文はdb.表名.find(query, projection);
次のとおりです
db はグローバル変数であり、固定されており、
find は select キーワードに似ています。find に加えて、
where キーワードの背後にある条件と同様の挿入、更新などのクエリがあります (オプションの場合、{} で囲む必要があります)
プロジェクション どのフィールドをクエリするか (オプションの場合、{} で囲む必要があります)
より一般的に使用されるクエリ構文のいくつかを以下に示します。
クエリ操作 | モンデータベース SQL | リレーショナルSQL | 述べる |
---|---|---|---|
すべてのデータ すべてのフィールド | db.t_user.find(); | select * from t_user; | |
名前=張さんを確認してください | db.t_user.find({“名前”:“張さん”}); | select * from t_user where name = “zhangsan”; | フィールド名は大文字と小文字が区別され、name と Name は同じフィールドではありません。and 条件が複数ある場合は、{} でカンマを区切ることができます。 |
名前を確認してください!=張さん | db.t_user.find({“名前”:{$ne:“張三”}}) | select * from t_user where name != “zhangsan”; | |
名前=nullをチェックしてください | db.t_user.find({“名前”:null}) | select * from t_user (名前は null) | 名前フィールドを持たないレコードはデフォルトでは null であり、この時点で条件が満たされる場合にクエリが実行されます。 |
名前と年齢のフィールドのみを確認してください | db.t_user.find({“名前”:“張さん”}, {名前:1,年齢:1}); | 名前 = "zhangsan" の t_user から名前、年齢を選択します。 | where 条件がない場合は、前の {} を空のままにしておきます。後の {} を省略すると、デフォルトですべてのフィールドを検索することを意味し、省略しない場合は、検索するフィールドをカスタマイズすることを意味します。フィールド名の後の数字は、そのフィールドが 1 表示されるか 0 表示されないことを示します。1/0 の代わりに true/false を使用することもできます |
クエリイン | db.t_user.find({“名前”:{$in:[“zhangsan”,“lisi”]}}); | select * from t_user where name in (“zhangsan”,“lisi”); | in はどれかを満たすことを意味し、nin は満たさないことを意味します = not in、all はすべてを満たすことを意味します |
クエリが含まれていません | db.t_user.find({name:{$nin:["zhangsan","lisi"]}}); | select * from t_user where name not in (“zhangsan”,“lisi”); | |
クエリまたは | db.t_user.find({“$or”:[{“名前”:“張三”},{“年齢”:18}]}); | select * from t_user where name = “zhangsan” または age = 18; | |
クエリの範囲 | db.t_user .find({“年齢”:{$ gte:18,$ lte:22}}) | select * from t_user ここで、年齢は 18 歳以上、年齢は 22 歳以下です。 | $lt $ge $lte $gte 代表 <、>、<=、>= |
ファジークエリ | db.t_user .find({“名前”: {“$regex”: /zhangsan/}}); | select * from t_user where name like '%zhangsan%'; | これらはすべて正規表現で、似たものです。zhang /^zhang/ で始まる場合は 'zhang%' と同等、zhang /zhang$/ で終わる場合は '%zhang' と同等、/zhang/i は大文字と小文字を無視します。 |
それは存在しますか | db.t_user.find({“年齢”:{$exists:true}}); | 年齢フィールドを含むレコードをクエリします。存在しないことを確認して false に変更します |
「クエリ結果」を再処理する方法は次のとおりです。
操作する | モンデータベース SQL | リレーショナルSQL | 述べる |
---|---|---|---|
データのフォーマット | db.t_user.find().pretty(); | json形式と同等 | |
重複排除 | db.t_user.find().distinct(“名前”); | t_user から別の名前を選択します。 | |
行を数える | db.t_user.find().count(); | t_user から count(*) を選択 | |
総括する | db.t_user.aggregate([{$ group:{_id:null,age:{$ sum:“$age”}}}]); | t_userから合計(年齢)を選択します | 同様に、平均化の場合は、sum を avg に変更します。その他には、min、max、push (クエリ結果を正方配列に入れる)、first (最初のものを取得する)、last などがあります。 |
最初の N 項目を確認してください | db.t_user.find().limit(10); | select * from t_user 制限 10 または select Top 10 * from t_user | 最初の 10 件を表示 |
最初のNにならないでください | db.t_user.find().skip(10); | select * from t_user where rowId > 10 | 最初の10項目は諦めないでください |
分類する | db.t_user.find().sort({age:-1}); | select * from t_user order by age desc | 1 つの順方向シーケンス - 1 つの逆方向シーケンス |
ページング | db.t_user.find().skip(10).limit(10) | select * from t_user 制限 10、20; | 第pageNo页时,skip=(pageNo-1)*pageSize,limit=pageSize (pageNo是当前页码 pageSize是每页条数 ) |
分页+排序 | db.t_user.find().skip(10).limit(10).sort({age:-1}); | select * from t_user limit 10, 20 order by age desc | skip(), limilt(), sort()这三个的执行顺序是先sort(),然后是skip(),最后是limit() |
分组 | db.t_user.find({$ group:{name: ‘$name’}}); | select * from t_user group by name; | |
查子集 | db.t_user.find({},{“name”:{“$slice”:10}}) | select * from t_user limit 10 | slice可从结果集里(根据某个字段)得到子集;10表查前10条,-10表示查后10条,[10,20] 表示查区间 |
下面是一些有用的javascript语法
操作 | mongdb SQL | 备注 |
---|---|---|
查某个key存在 | db.t_user.find({“age”:{$exists:true}}); | 不存在改成false |
过滤key不存在的记录 | db.t_user.find({age:{“$ in”:[null], “$ exists”:true}}) | age = null或age不存在的都会被查询出来,通过exists过滤不存在只留下age=null的 |
定义参数的查询 | var start = new Date(“11/03/2023”); // 定义变量并赋值 db.t_user.find({createTime:{$ lte:start}}) // 根据按时间查询 | 或者 db.t_user.find({createTime:{$gt:ISODate(“2023-03-11T00:00:00Z”)}}); |
既有where条件同时有函数 | db.t_user.aggregate([{$ match:{createTime:{$ gte:ISODate(“2020-11-10T00:00:00Z”),$ lt:ISODate(“2020-11-11T00:00:00Z”)}}},{$ group:{_id:null,age:{$ sum:“$age”}}}]) | 等同SELECT SUM(age) from t_user where createTime >= ‘2020-11-10 00:00:00’ and createTime < ‘2020-11-11 00:00:00’; |
下面是一些拓展功能参考
# 遍历集合 注:游标10分钟内没有使用会自动销毁(immortal函数可设置超时不销毁)
var cursor=db.t_user.find(); //定义游标,使用forEach循环
cursor.forEach(function(f){
print(f.name,f.age); // 循环打印姓名 年纪
});
或者
var cursor=db.t_user.find(); //定义游标
while(cursor.hasNext()){
var f = cursor.next();
print(f.name,f.age); // 循环打印姓名 年纪
}
# 随机查询一条 等价SELECT * FROM t_user ORDER BY RAND() limit 1
var total = db.t_user.count(); // 查询总数
var random = Math.floor(Math.random()*total); // 根据总数取个随机值random
db.t_user.skip(random).limit(1); // 前random条舍弃,从剩下的里面取第一条
# 插入数据
db.t_user.insert([
{
"_id" : 1, "userId" : "u1", "name" : "zhangsan", "age" : "15" },
{
"_id" : 2, "userId" : "u2", "name" : "lisi", "age" : "22" }
]);
关于insert、insertOne、insertMany、save的区别
insert和insertMany 一次可以插入多条。可以搭配{
ordered:true}使用。ordered为是否按顺序写入之意,默认true。即中间某条插入失败时,true则中断不执行后续,false可以继续执行后面的
insertOne和save 一次只能插入一条,多条报错。且前者若主键冲突报错,后者则覆盖旧数据
# 关联查询 类似于 select info.* from t_user_info info left join t_user u on info.user_id = u.user_id where info.name = 'zhangsan'
db.t_user_info.aggregate([
{
$lookup: # 表示表关联查询
{
from: "t_user", # 被关联的表名称
localField: "user_id", # 关联字段:t_user_info.user_id
foreignField: "user_id", # 关联字段: t_user.user_id
as: "userInfo" # 结果集别名
}
},
{
$match : {
"name" :"zhangsan"} } # where条件进行过滤
])
# 根据姓名分组查数量 select name as _id, count(*) as num from t_user group by name
db.t_user.aggregate([
{
$group: {
# 分组
_id: '$name', # 根据什么字段字段进行分组,这里是根据name字段。'$name'也可以改成null表示只分一个组,目的一般用于求和求平均数等场景
num: {
$sum: 1} # 每个分组数量 * 1 (1不是固定值可以改成别的数字)
# ageArray: {
$push: '$age'} # 把每个组的age字段放在ageArray这个数组字段里面, 所以push有点类似wm_concat()函数,数组拼接和逗号拼接的格式区别而已
}
}
])
# 综合查询 select name, age from t_user where age > 20 group by name limit 10,20 order by name desc
db.t_user.aggregate([
{
$project: {
// 需要查询哪些字段
_id: 0, // _id字段不查
name: 1 // name和age字段查
age: 1
}
},
{
$match: {
age: {
$gt: 20} // 匹配条件 年纪大于20的
}
},
{
$group: {
name: '$name', // 根据name分组
}
},
{
$sort: {
name: -1 // 根据name倒叙
}
},
{
$skip: 10
},
{
$limit: 10
}
])
查询用 find(普通查询) 和 aggregate(聚合查询) 都可以,但后者的效率好一点。find是用{}来接收查询条件,aggregate用数组[]来接收查询条件。如果用aggregate,根据下面表格可以快速记忆下来,配合上面的示例就可以写出符合需求的脚本语句了。
关系型数据库 关键词 | monggodb 关键词 |
---|---|
where/having | match |
group by | group |
order by | sort |
sum/count | sum |
join | lookup |
concat | push |
limit | limit |
max | max |
min | min |