MonogDB中对数组类型的查询主要包括以下几种情况:
- 查询整个数组要求元素内容和元素顺序必须完全相同
- 查询数组中的元素(普通元素),包含两种情况:
- 与位置无关,查询数组中含有某个值的元素,例如:db.student.find({score: 80})
- 与位置有关,按照指定的数组索引查询数组元素的值(使用点号操作符),例如:db.student.find({'scores.2': 95})
- 数组元素是文档时,查询数组元素包含两种情况:
- 与位置无关,查询数组中满足条件的子文档元素,例如:db.student.find( {'scores.成绩’:95})
- 与位置有关,按照指定的数组索引查询数组子文档,例如:db.student.find( {'scores.2.成绩’:95})
针对数组MongoDB提供了数组操作符,可以实现非常复杂的数组操作, 用于条件查询和数组元素的映射。
条件查询 | 作用 | 元素映射 | 作用 |
$all | 定元素的文档 | $ | 元素 |
$elemMatch | 多条件查询 | $elemMatch | 子集 |
$size | 查询指定长度的数组 | $slice | 集 |
条件查询实例
var db = connect("localhost:27017/test");
db.col.drop();
var bulk = db.col.initializeUnorderedBulkOp();
//测试数据
var doc1=
{ _id: 1,
name: "xiaoli",
age: 20,
scores: [
{ 课程:"语文",成绩:90},
{ 课程:"数学",成绩:95}
]
}
bulk.insert(doc1);
var doc2=
{ _id: 2,
name: "xiaoqiang",
age: 22,
scores: [
{ 课程:"语文",成绩:92},
{ 课程:"英语",成绩:90}
]
}
bulk.insert(doc2);
//下面执行插入操作
bulk.execute();
print("===与位置无关,查询数组中含有某个值的元素===");
var cursor = db.col.find({'scores.成绩':90});
printjson(cursor.toArray());
print("===与位置有关,按照指定的数组索引查询数组元素的值(使用点号操作符)===");
cursor = db.col.find({'scores.1.成绩':90})
printjson(cursor.toArray());
print("========find--$elemMatch操作符(多条件查询条件)的使用========")
var cursor = db.col.find( {
scores:
{
$elemMatch: {"课程":"语文","成绩":90}
}
}
);
printjson(cursor.toArray());
print("===$all查询参数数组中包含指定元素的文档===");
cursor = db.col.find({
scores:{
"$all":[{"课程":"语文","成绩":90}]
}
});
printjson(cursor.toArray());
print("===$size查询指定长度的数组===");
cursor = db.col.find({
scores:{
"$size":2
}
});
printjson(cursor.toArray());
运行结果:
C:\>mongo --quiet find_array_embedded.js
===与位置无关,查询数组中含有某个值的元素===
[
{
"_id" : 1,
"name" : "xiaoli",
"age" : 20,
"scores" : [
{
"课程" : "语文",
"成绩" : 90
},
{
"课程" : "数学",
"成绩" : 95
}
]
},
{
"_id" : 2,
"name" : "xiaoqiang",
"age" : 22,
"scores" : [
{
"课程" : "语文",
"成绩" : 92
},
{
"课程" : "英语",
"成绩" : 90
}
]
}
]
===与位置有关,按照指定的数组索引查询数组元素的值(使用点号操作符)===
[
{
"_id" : 2,
"name" : "xiaoqiang",
"age" : 22,
"scores" : [
{
"课程" : "语文",
"成绩" : 92
},
{
"课程" : "英语",
"成绩" : 90
}
]
}
]
========find--$elemMatch操作符(多条件查询条件)的使用========
[
{
"_id" : 1,
"name" : "xiaoli",
"age" : 20,
"scores" : [
{
"课程" : "语文",
"成绩" : 90
},
{
"课程" : "数学",
"成绩" : 95
}
]
}
]
===$all查询参数数组中包含指定元素的文档===
[
{
"_id" : 1,
"name" : "xiaoli",
"age" : 20,
"scores" : [
{
"课程" : "语文",
"成绩" : 90
},
{
"课程" : "数学",
"成绩" : 95
}
]
}
]
===$size查询参数数组中包含指定元素的文档===
[
{
"_id" : 1,
"name" : "xiaoli",
"age" : 20,
"scores" : [
{
"课程" : "语文",
"成绩" : 90
},
{
"课程" : "数学",
"成绩" : 95
}
]
},
{
"_id" : 2,
"name" : "xiaoqiang",
"age" : 22,
"scores" : [
{
"课程" : "语文",
"成绩" : 92
},
{
"课程" : "英语",
"成绩" : 90
}
]
}
]
元素映射的使用
var db = connect("localhost:27017/test");
db.col.drop();
var bulk = db.col.initializeUnorderedBulkOp();
//测试数据
var doc1=
{ _id: 1,
name: "xiaoli",
age: 20,
scores: [
{ 课程:"语文",成绩:90},
{ 课程:"数学",成绩:95}
]
}
bulk.insert(doc1);
var doc2=
{ _id: 2,
name: "xiaoqiang",
age: 22,
scores: [
{ 课程:"语文",成绩:92},
{ 课程:"英语",成绩:90}
]
}
bulk.insert(doc2);
//下面执行插入操作
bulk.execute();
print("===$elemMatch按条件返回数组元素的子集===");
var cursor = db.col.find({},
{_id:1,
name:1,
age:1,
scores:{
$elemMatch: {"课程":"语文","成绩":90}
}
});
printjson(cursor.toArray());
print("===$slice返回连续数组元素的子集===");
/**
$slice:2 表示返回数组中的前两个元素
$slice:-2 表示数组中的后两个元素
$slice : [2,1],表示从第二个3元素开始取1个,如果获取数量大于2后面的元素数量,则取后面的全部数据
*/
var cursor = db.col.find({},
{_id:1,
name:1,
age:1,
scores:{
$slice: [1,1] //从第二个元素开始取一个
}
});
printjson(cursor.toArray());
运行结果:
C:\>mongo --quiet find_array_embedded.js
===$elemMatch按条件返回数组元素的子集===
[
{
"_id" : 1,
"name" : "xiaoli",
"age" : 20,
"scores" : [
{
"课程" : "语文",
"成绩" : 90
}
]
},
{
"_id" : 2,
"name" : "xiaoqiang",
"age" : 22
}
]
===$slice返回连续数组元素的子集===
[
{
"_id" : 1,
"name" : "xiaoli",
"age" : 20,
"scores" : [
{
"课程" : "数学",
"成绩" : 95
}
]
},
{
"_id" : 2,
"name" : "xiaoqiang",
"age" : 22,
"scores" : [
{
"课程" : "英语",
"成绩" : 90
}
]
}
]
C:\>