MongoDB

MongoDB 知识量:13 - 42 - 129

3.3 特定类型的查询><

查询数组- 3.3.1 -

在 MongoDB 中,查询数组类型的字段非常灵活,可以使用多种操作符来匹配数组中的元素。以下是一些常见的查询数组字段的示例:

1. 精确匹配数组中的元素

// 查找 hobbies 字段中包含 "reading" 的所有文档      
db.users.find({ hobbies: "reading" })

这个查询会匹配 hobbies 数组中包含字符串 "reading" 的所有文档。

2. 使用 $all 匹配数组中的多个元素

// 查找 hobbies 字段中同时包含 "reading" 和 "writing" 的所有文档      
db.users.find({ hobbies: { $all: ["reading", "writing"] } })

3. 使用 $in 匹配数组中的任意元素

// 查找 hobbies 字段中包含 "reading" 或 "gaming" 的所有文档  
db.users.find({ "hobbies": "reading" }) // 匹配包含 "reading" 的数组  
db.users.find({ "hobbies": "gaming" }) // 匹配包含 "gaming" 的数组  
// 以上只能匹配单个元素。如果想匹配多个元素中的任意一个,需要使用 $or:  
db.users.find({ $or: [{ hobbies: "reading" }, { hobbies: "gaming" }] })

4. 使用 $size 匹配数组长度

// 查找 hobbies 字段数组长度为 3 的所有文档      
db.users.find({ hobbies: { $size: 3 } })

5. 使用 $elemMatch 匹配数组中的对象

当数组字段包含对象时,可以使用 $elemMatch 来匹配数组中的对象。

// 查找 scores 数组中有一个元素大于等于 80 并且小于等于 90 的所有文档      
db.students.find({ scores: { $elemMatch: { $gte: 80, $lte: 90 } } })

6. 数组字段的更新

当更新数组字段时,可以使用各种更新操作符,如 $push、$pop、$pull、$pullAll、$addToSet 等。

// 向 hobbies 数组中添加一个元素 "painting"  
db.users.updateOne({ _id: ObjectId("someId") }, { $push: { hobbies: "painting" } })  
  
// 从 hobbies 数组中删除最后一个元素  
db.users.updateOne({ _id: ObjectId("someId") }, { $pop: { hobbies: -1 } })  
  
// 从 hobbies 数组中删除所有 "reading" 元素  
db.users.updateMany({}, { $pull: { hobbies: "reading" } })  
  
// 向 scores 数组中添加一个对象,但只有当该对象不在数组中时才添加  
db.students.updateOne(  
  { _id: ObjectId("someStudentId") },  
  { $addToSet: { scores: { score: 85, date: new Date() } } }  
)

注意:当使用更新操作符时,需要指定查询条件来选择要更新的文档(除了 updateMany,它会更新所有匹配的文档)。在上面的示例中,使用了 _id 字段作为查询条件,但可以根据需要使用其他字段。

查询内嵌文档- 3.3.2 -

在 MongoDB 中,查询内嵌文档(embedded documents)可以通过点表示法(dot notation)来完成。内嵌文档是存储在另一个文档内部的文档。使用点表示法,可以访问内嵌文档中的字段,并在查询、更新和投影中使用它们。

以下是查询内嵌文档的一些常见示例:

1. 查询内嵌文档中的字段

假设有一个名为 users 的集合,其中的文档包含一个名为 contact 的内嵌文档,可以这样查询 contact 中的 email 字段:

db.users.find({"contact.email": "example@example.com"})

这个查询会返回所有 users 集合中 contact.email 字段值为 "example@example.com" 的文档。

2. 查询内嵌文档中的数组字段的元素

如果内嵌文档中还包含数组字段,可以使用点表示法结合数组索引来查询特定元素。例如,要查询 contact 文档中 phoneNumbers 数组的第一个元素:

db.users.find({"contact.phoneNumbers.0": "123-456-7890"})

注意:这种查询方式只会匹配数组在指定位置具有特定值的文档。

3. 使用比较操作符查询内嵌文档

可以在查询中使用比较操作符,如 $gt、$lte 等,来比较内嵌文档中的字段值。例如:

db.users.find({"contact.age": {$gt: 18}})

这个查询会返回所有 users 集合中 contact.age 字段值大于 18 的文档。

4. 使用 $elemMatch 查询内嵌文档数组

如果内嵌文档是一个数组,并且想基于数组中对象的多个字段进行查询,可以使用 $elemMatch 操作符。例如:

db.users.find({  
  "contact.addresses": {  
    $elemMatch: { street: "123 Main St", city: "Anytown" }  
  }  
})

这个查询会返回 users 集合中 contact.addresses 数组至少有一个元素其 street 是 "123 Main St" 且 city 是 "Anytown" 的文档。

5. 查询内嵌文档的存在性

如果想确保内嵌文档存在,即使不关心它的具体内容,可以使用 $exists 操作符:

db.users.find({"contact.email": {$exists: true}})

这个查询会返回所有包含 contact.email 字段的 users 文档,无论该字段的值是什么。

6. 查询内嵌文档并返回特定字段

在投影(projection)中,也可以使用点表示法来指定返回的字段。例如,如果只想返回 contact 文档中的 email 和 name 字段:

db.users.find({}, {"contact.email": 1, "contact.name": 1})

这个查询会返回 users 集合中的所有文档,但结果中只包含 contact 文档的 email 和 name 字段。