查询 MongoDB 数组

MongoDBMongoDBBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

介绍

在本实验中,你将学习如何有效地查询 MongoDB 中的数组。实验涵盖了多种技术,包括在数组中搜索特定元素、使用数组运算符进行更复杂的查询、通过数组大小查找文档、匹配元素位置以及过滤数组值。这些技能对于处理 MongoDB 提供的强大数据结构至关重要,使你能够高效地检索和操作存储在数组字段中的数据。

实验将通过实际示例引导你,从创建示例集合开始,然后探索不同的查询方法。在本实验结束时,你将深入了解如何利用 MongoDB 的数组查询功能来满足你的数据管理需求。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL mongodb(("MongoDB")) -.-> mongodb/QueryOperationsGroup(["Query Operations"]) mongodb(("MongoDB")) -.-> mongodb/DataTypesGroup(["Data Types"]) mongodb(("MongoDB")) -.-> mongodb/ArrayandEmbeddedDocumentsGroup(["Array and Embedded Documents"]) mongodb/QueryOperationsGroup -.-> mongodb/find_documents("Find Documents") mongodb/DataTypesGroup -.-> mongodb/work_with_array_data_types("Work with Array Data Types") mongodb/DataTypesGroup -.-> mongodb/manage_array_elements("Manage Array Elements") mongodb/ArrayandEmbeddedDocumentsGroup -.-> mongodb/query_embedded_documents("Query Embedded Documents") subgraph Lab Skills mongodb/find_documents -.-> lab-422090{{"查询 MongoDB 数组"}} mongodb/work_with_array_data_types -.-> lab-422090{{"查询 MongoDB 数组"}} mongodb/manage_array_elements -.-> lab-422090{{"查询 MongoDB 数组"}} mongodb/query_embedded_documents -.-> lab-422090{{"查询 MongoDB 数组"}} end

搜索数组元素

在这一步骤中,我们将探索如何在 MongoDB 数组中搜索元素。数组是一种强大的数据结构,允许你在单个字段中存储多个值,而 MongoDB 提供了灵活的方式来查询这些数组。

首先,让我们启动 MongoDB shell 并创建一个包含数组数据的示例集合:

mongosh

接下来,创建一个数据库并插入一些包含数组字段的文档:

use arraylab

db.products.insertMany([
    {
        name: "Laptop",
        tags: ["electronics", "computer", "work"],
        colors: ["silver", "black", "blue"]
    },
    {
        name: "Smartphone",
        tags: ["electronics", "mobile", "communication"],
        colors: ["red", "blue", "green"]
    },
    {
        name: "Headphones",
        tags: ["electronics", "audio", "music"],
        colors: ["black", "white"]
    }
])

让我们搜索包含数组中特定元素的文档:

db.products.find({ tags: "electronics" });

此查询将返回所有在 tags 数组中包含 "electronics" 的文档。

示例输出:

[
  {
    _id: ObjectId("..."),
    name: 'Laptop',
    tags: [ 'electronics', 'computer', 'work' ],
    colors: [ 'silver', 'black', 'blue' ]
  },
  {
    _id: ObjectId("..."),
    name: 'Smartphone',
    tags: [ 'electronics', 'mobile', 'communication' ],
    colors: [ 'red', 'blue', 'green' ]
  },
  {
    _id: ObjectId("..."),
    name: 'Headphones',
    tags: [ 'electronics', 'audio', 'music' ],
    colors: [ 'black', 'white' ]
  }
]

你还可以搜索数组中包含多个特定元素的文档:

db.products.find({ colors: { $all: ["black", "blue"] } });

此查询会找到在 colors 数组中同时包含 "black""blue" 的产品。

使用数组运算符

在这一步骤中,我们将深入探讨 MongoDB 数组查询,学习一些强大的数组运算符,这些运算符可以实现更复杂和精确的搜索。

我们将继续使用上一步中的数据库和集合。如果你已经关闭了 MongoDB shell,请重新启动并选择数据库:

mongosh
use arraylab

首先,我们来学习 $elemMatch 运算符,它允许匹配至少一个数组元素满足多个条件的文档:

db.products.insertMany([
  {
    name: "Gaming Laptop",
    specs: [
      { ram: 16, storage: 512, price: 1200 },
      { ram: 32, storage: 1024, price: 2000 }
    ]
  },
  {
    name: "Office Laptop",
    specs: [
      { ram: 8, storage: 256, price: 600 },
      { ram: 16, storage: 512, price: 800 }
    ]
  }
]);

// 查找规格中 RAM >= 16 且价格 > 1000 的笔记本电脑
db.products.find({
  specs: {
    $elemMatch: {
      ram: { $gte: 16 },
      price: { $gt: 1000 }
    }
  }
});

接下来,我们探索 $size 运算符,用于查找具有特定长度数组的文档:

// 查找颜色数组长度恰好为 2 的产品
db.products.find({ colors: { $size: 2 } });

我们还将演示 $slice 运算符,用于检索数组元素的子集:

// 仅检索每个产品的前两个标签
db.products.find({}, { tags: { $slice: 2 } });

示例输出:

[
  {
    _id: ObjectId("..."),
    name: 'Laptop',
    tags: [ 'electronics', 'computer' ]
  },
  {
    _id: ObjectId("..."),
    name: 'Smartphone',
    tags: [ 'electronics', 'mobile' ]
  }
]

根据数组大小查找

在这一步骤中,我们将探索如何根据数组的大小查询 MongoDB 文档。$size 运算符允许你查找具有特定数量元素的数组的文档。

首先,启动 MongoDB shell 并确保我们使用的是之前的数据库:

mongosh
use arraylab

让我们添加一些具有不同数组大小的文档来演示查询:

db.products.insertMany([
  {
    name: "Basic Laptop",
    features: ["wifi"],
    accessories: ["charger"]
  },
  {
    name: "Advanced Laptop",
    features: ["wifi", "bluetooth", "touchscreen"],
    accessories: ["charger", "mouse", "case"]
  },
  {
    name: "Premium Laptop",
    features: ["wifi", "bluetooth", "touchscreen", "4K display"],
    accessories: ["charger", "mouse", "case", "keyboard"]
  }
]);

现在,让我们查询具有特定大小数组的文档:

// 查找具有恰好 1 个功能的产品
db.products.find({ features: { $size: 1 } });

// 查找具有 3 个功能的产品
db.products.find({ features: { $size: 3 } });

// 查找具有 4 个配件的产品
db.products.find({ accessories: { $size: 4 } });

示例输出:

// 具有 1 个功能的产品
[
  {
    _id: ObjectId("..."),
    name: 'Basic Laptop',
    features: [ 'wifi' ],
    accessories: [ 'charger' ]
  }
]

// 具有 3 个功能的产品
[
  {
    _id: ObjectId("..."),
    name: 'Advanced Laptop',
    features: [ 'wifi', 'bluetooth', 'touchscreen' ],
    accessories: [ 'charger', 'mouse', 'case' ]
  }
]

// 具有 4 个配件的产品
[
  {
    _id: ObjectId("..."),
    name: 'Premium Laptop',
    features: [ 'wifi', 'bluetooth', 'touchscreen', '4K display' ],
    accessories: [ 'charger', 'mouse', 'case', 'keyboard' ]
  }
]

你还可以将 $size 运算符与其他查询条件结合使用:

// 查找具有恰好 3 个功能且配件数量大于 2 的产品
db.products.find({
  features: { $size: 3 },
  accessories: { $size: { $gt: 2 } }
});

匹配元素位置

在这一步骤中,我们将学习如何通过匹配特定元素位置来查询 MongoDB 数组。MongoDB 提供了强大的功能,可以在数组中的确切位置搜索元素。

首先,启动 MongoDB shell 并确保我们使用的是之前的数据库:

mongosh
use arraylab

让我们创建一个新的集合,其中包含一些数组元素位置重要的文档:

db.courses.insertMany([
  {
    name: "Web Development Bootcamp",
    modules: ["HTML", "CSS", "JavaScript", "React", "Node.js"],
    difficulty: ["beginner", "intermediate", "advanced"]
  },
  {
    name: "Data Science Course",
    modules: [
      "Python",
      "Statistics",
      "Machine Learning",
      "Deep Learning",
      "AI"
    ],
    difficulty: ["intermediate", "advanced", "expert"]
  },
  {
    name: "Cybersecurity Program",
    modules: [
      "Network Security",
      "Ethical Hacking",
      "Cryptography",
      "Penetration Testing",
      "Incident Response"
    ],
    difficulty: ["intermediate", "advanced", "expert"]
  }
]);

现在,让我们通过匹配特定数组位置的元素来查询文档:

// 查找第一个模块为 "HTML" 的课程
db.courses.find({ "modules.0": "HTML" });

// 查找第三个模块为 "JavaScript" 的课程
db.courses.find({ "modules.2": "JavaScript" });

// 查找第二个难度级别为 "advanced" 的课程
db.courses.find({ "difficulty.1": "advanced" });

示例输出:

// 第一个模块为 HTML 的课程
[
  {
    _id: ObjectId("..."),
    name: 'Web Development Bootcamp',
    modules: [ 'HTML', 'CSS', 'JavaScript', 'React', 'Node.js' ],
    difficulty: [ 'beginner', 'intermediate', 'advanced' ]
  }
]

// 第三个模块为 JavaScript 的课程
[
  {
    _id: ObjectId("..."),
    name: 'Web Development Bootcamp',
    modules: [ 'HTML', 'CSS', 'JavaScript', 'React', 'Node.js' ],
    difficulty: [ 'beginner', 'intermediate', 'advanced' ]
  }
]

// 第二个难度级别为 "advanced" 的课程
[
  {
    _id: ObjectId("..."),
    name: 'Data Science Course',
    modules: [ 'Python', 'Statistics', 'Machine Learning', 'Deep Learning', 'AI' ],
    difficulty: [ 'intermediate', 'advanced', 'expert' ]
  },
  {
    _id: ObjectId("..."),
    name: 'Cybersecurity Program',
    modules: [ 'Network Security', 'Ethical Hacking', 'Cryptography', 'Penetration Testing', 'Incident Response' ],
    difficulty: [ 'intermediate', 'advanced', 'expert' ]
  }
]

你还可以将基于位置的查询与其他条件结合使用:

// 查找第一个模块为 "HTML" 且第二个难度级别为 "intermediate" 的课程
db.courses.find({
  "modules.0": "HTML",
  "difficulty.1": "intermediate"
});

过滤数组值

在这最后一步中,我们将探索在 MongoDB 中过滤数组值的高级技术,使用比较和逻辑运算符来创建复杂的查询。

首先,启动 MongoDB shell 并确保我们使用的是之前的数据库:

mongosh
use arraylab

让我们创建一个包含更复杂数组结构的产品集合:

db.electronics.insertMany([
  {
    name: "Smartphone",
    specs: [
      { ram: 6, storage: 128, price: 499 },
      { ram: 8, storage: 256, price: 599 }
    ],
    tags: ["mobile", "communication", "high-end"],
    ratings: [4.5, 4.7, 4.6]
  },
  {
    name: "Laptop",
    specs: [
      { ram: 16, storage: 512, price: 1200 },
      { ram: 32, storage: 1024, price: 2000 }
    ],
    tags: ["computer", "work", "professional"],
    ratings: [4.8, 4.9, 4.7]
  },
  {
    name: "Tablet",
    specs: [
      { ram: 4, storage: 64, price: 299 },
      { ram: 8, storage: 256, price: 499 }
    ],
    tags: ["mobile", "entertainment"],
    ratings: [4.2, 4.3, 4.1]
  }
]);

让我们探索不同的过滤技术:

  1. 通过数组元素比较进行过滤:
// 查找至少有一个规格中 RAM >= 16 的设备
db.electronics.find({
  specs: {
    $elemMatch: { ram: { $gte: 16 } }
  }
});

// 查找评分高于 4.5 的设备
db.electronics.find({
  ratings: { $gt: 4.5 }
});
  1. 使用逻辑运算符与数组结合:
// 查找同时具有 "mobile" 和 "communication" 标签的设备
db.electronics.find({
  tags: { $all: ["mobile", "communication"] }
});

// 查找具有 "work" 或 "entertainment" 标签的设备
db.electronics.find({
  tags: { $in: ["work", "entertainment"] }
});
  1. 使用多个条件进行复杂过滤:
// 查找规格中 RAM >= 8 且价格 <= 1000 的设备
db.electronics.find({
  specs: {
    $elemMatch: {
      ram: { $gte: 8 },
      price: { $lte: 1000 }
    }
  }
});

示例输出:

// RAM >= 16 的设备
[
  {
    _id: ObjectId("..."),
    name: 'Laptop',
    specs: [
      { ram: 16, storage: 512, price: 1200 },
      { ram: 32, storage: 1024, price: 2000 }
    ],
    tags: [ 'computer', 'work', 'professional' ],
    ratings: [ 4.8, 4.9, 4.7 ]
  }
]

// 评分高于 4.5 的设备
[
  {
    _id: ObjectId("..."),
    name: 'Smartphone',
    ratings: [ 4.5, 4.7, 4.6 ]
  },
  {
    _id: ObjectId("..."),
    name: 'Laptop',
    ratings: [ 4.8, 4.9, 4.7 ]
  }
]

总结

在本实验中,你学习了如何在 MongoDB 数组中搜索元素,使用各种数组运算符来执行更复杂和精确的搜索。你探索了基于数组中特定元素的存在、数组元素的大小和位置来查找文档的技术。这些技能使你能够有效地查询和操作存储在 MongoDB 灵活数组数据结构中的数据,从而构建强大且高效的应用程序。