使用文档

作为文档数据库,Amazon DocumentDB 可以轻松存储、查询和索引 JSON 数据。在 Amazon DocumentDB 中,除了没有对所有文档强制实施单一架构外,文档数据库集合类似于关系数据库中的表。集合允许您将类似的文档分组在一起,同时将它们保存在同一数据库中,而不需要它们在结构上相同。

使用前面部分中的示例文档,您可能会有针对 reading_materialoffice_supplies 的集合。 您的软件有责任强制执行文档属于哪个集合。

以下示例使用 MongoDB API 来展示如何添加、查询、更新和删除文档。

添加文档

在 Amazon DocumentDB 中,首次向集合添加文档时会创建数据库。在此示例中,您将在 test 数据库中创建名为 example 的集合,该集合是连接到集群时的默认数据库。因为在插入第一个文档时隐式创建集合,所以集合名称没有错误检查。因此,集合名称中的拼写错误(例如 eexample 而不是 example)将创建文档并将其添加到 eexample 集合,而不是预期集合中。错误检查必须由您的应用程序进行处理。

以下示例使用 MongoDB API 添加文档。

添加单个文档

要将单个文档添加至集合,请使用带有您想添加至集合的文档的 insertOne( {} ) 操作。

  1. db.example.insertOne(
  2. {
  3. "Item": "Ruler",
  4. "Colors": ["Red","Green","Blue","Clear","Yellow"],
  5. "Inventory": {
  6. "OnHand": 47,
  7. "MinOnHand": 40
  8. },
  9. "UnitPrice": 0.89
  10. }
  11. )

此操作的输出将类似于下文(JSON 格式)。

  1. {
  2. "acknowledged" : true,
  3. "insertedId" : ObjectId("5bedafbcf65ff161707de24f")
  4. }

添加多个文档

要将多个文档添加至集合,请使用带有您想添加至集合的文档列表的 insertMany( [{},...,{}] ) 操作。虽然此特定列表中的文档具有不同的架构,但它们都可以添加至同一个集合。

  1. db.example.insertMany(
  2. [
  3. {
  4. "Item": "Pen",
  5. "Colors": ["Red","Green","Blue","Black"],
  6. "Inventory": {
  7. "OnHand": 244,
  8. "MinOnHand": 72
  9. }
  10. },
  11. {
  12. "Item": "Poster Paint",
  13. "Colors": ["Red","Green","Blue","Black","White"],
  14. "Inventory": {
  15. "OnHand": 47,
  16. "MinOnHand": 50
  17. }
  18. },
  19. {
  20. "Item": "Spray Paint",
  21. "Colors": ["Black","Red","Green","Blue"],
  22. "Inventory": {
  23. "OnHand": 47,
  24. "MinOnHand": 50,
  25. "OrderQnty": 36
  26. }
  27. }
  28. ]
  29. )

此操作的输出将类似于下文(JSON 格式)。

  1. {
  2. "acknowledged" : true,
  3. "insertedIds" : [
  4. ObjectId("5bedb07941ca8d9198f5934c"),
  5. ObjectId("5bedb07941ca8d9198f5934d"),
  6. ObjectId("5bedb07941ca8d9198f5934e")
  7. ]
  8. }

查询文档

有时,您可能需要查看在线商店的库存,这样客户就能看到并购买您销售的物品。查询集合相对容易,无论您想要集合中的所有文档,还是仅需要那些满足特定标准的文档。

要查询文档,请使用 find() 操作。find() 命令具有单个文档参数,该参数定义了在选择要返回的文档时要使用的标准。find() 的输出是一个文档,其格式为一行文本,不含换行符。要设置输出文档的格式以方便阅读,请使用 find().pretty()。 本主题中的所有示例都使用 .pretty() 设置输出的格式。

使用您在前两个练习(insertOne()insertMany())中插入到 example 集合中的四个文档。

检索集合中的所有文档

要检索集合中的所有文档,请将 find() 操作和空查询文档结合使用。

以下查询返回 example 集合中的所有文档。

  1. db.example.find( {} ).pretty()

检索与字段值匹配的文档

要检索与字段和值匹配的所有文档,请将 find() 操作和查询文档(标识要匹配的字段和值)结合使用。

通过使用前述文档,此查询将返回其中“Item”字段等于“Pen”的所有文档。

  1. db.example.find( { "Item": "Pen" } ).pretty()

检索与嵌入文档匹配的文档

要查找与嵌入文档匹配的所有文档,请将 find() 操作和查询文档(指定嵌入文档名称和嵌入文档的所有字段和值)结合使用。

在与嵌入文档匹配时,该文档的嵌入文档的名称必须与查询中的名称相同。此外,嵌入文档中的字段和值必须与查询匹配。

以下查询仅返回“Poster Paint”文档。这是因为“Pen”具有不同的“OnHand”和“MinOnHand”值,并且“Spray Paint”比查询文档多一个字段 (OrderQnty)。

  1. db.example.find({"Inventory": {
  2. "OnHand": 47,
  3. "MinOnHand": 50 } } ).pretty()

检索与嵌入文档中的字段值匹配的文档

要查找与嵌入文档匹配的所有文档,请将 find() 操作和查询文档(指定嵌入文档名称和嵌入文档的所有字段和值)结合使用。

考虑到上述文档,以下查询使用“点表示法”来指定嵌入文档和感兴趣的字段。将返回所有与这些内容匹配的文档,而不管嵌入文档中可能存在哪些其他字段。此查询将返回“Poster Paint”和“Spray Paint”,因为它们与指定的字段和值匹配。

  1. db.example.find({"Inventory.OnHand": 47, "Inventory.MinOnHand": 50 }).pretty()

检索与数组匹配的文档

要查找所有与数组匹配的文档,请将 find() 操作和您感兴趣的数组名称以及数组中的所有值结合使用。此查询将返回所有包含带该名称的数组(其中数组值和顺序与查询中的完全相同)的文档。

以下查询仅返回“Pen”,因为“Poster Paint”具有其他颜色 (White),并且“Spray Paint”具有顺序不同的颜色。

  1. db.example.find( { "Colors": ["Red","Green","Blue","Black"] } ).pretty()

检索与数组中的值匹配的文档

要查找所有具有特定数组值的文档,请将 find() 操作与您感兴趣的数组名称和值结合使用。

  1. db.example.find( { "Colors": "Red" } ).pretty()

上述操作将返回所有三个文档,因为它们都有一个名为 Colors 的数组,并且此数组中的某个位置具有“Red”值。如果您指定值“White”,则查询将仅返回“Poster Paint”。

使用运算符检索文档

以下查询返回“Inventory.OnHand”值小于 50 的所有文档。

  1. db.example.find(
  2. { "Inventory.OnHand": { $lt: 50 } } )

有关支持的查询运算符的列表,请参阅 查询和投影运算符

更新文档

通常,您的文档不是静态的,而是作为应用程序工作流的一部分进行更新。以下示例展示了更新文档的一些方法。

要更新现有文档,请使用 update() 操作。update() 操作具有两个文档参数。第一个文档标识要更新的文档。第二个文档指定要进行的更新。

在更新现有字段 — 时,无论该字段是简单字段、数组还是嵌入文档 —,都请指定字段名及其值。在操作结束时,旧文档中的字段似乎已替换为新的字段和值。

更新现有字段的值

在下面的更新操作中,使用您之前添加的以下四个文档。

  1. {
  2. "Item": "Ruler",
  3. "Colors": ["Red","Green","Blue","Clear","Yellow"],
  4. "Inventory": {
  5. "OnHand": 47,
  6. "MinOnHand": 40
  7. },
  8. "UnitPrice": 0.89
  9. },
  10. {
  11. "Item": "Pen",
  12. "Colors": ["Red","Green","Blue","Black"],
  13. "Inventory": {
  14. "OnHand": 244,
  15. "MinOnHand": 72
  16. }
  17. },
  18. {
  19. "Item": "Poster Paint",
  20. "Colors": ["Red","Green","Blue","Black","White"],
  21. "Inventory": {
  22. "OnHand": 47,
  23. "MinOnHand": 50
  24. }
  25. },
  26. {
  27. "Item": "Spray Paint",
  28. "Colors": ["Black","Red","Green","Blue"],
  29. "Inventory": {
  30. "OnHand": 47,
  31. "MinOnHand": 50,
  32. "OrderQnty": 36
  33. }
  34. }

更新简单字段

要更新简单字段,请将 update()$set 结合使用以指定字段名和新值。以下示例将 Item 从“Pen”更改为“Gel Pen”。

  1. db.example.update(
  2. { "Item" : "Pen" },
  3. { $set: { "Item": "Gel Pen" } }
  4. )

此操作的结果将类似于下文。

  1. {
  2. "Item": "Gel Pen",
  3. "Colors": ["Red","Green","Blue","Black"],
  4. "Inventory": {
  5. "OnHand": 244,
  6. "MinOnHand": 72
  7. }
  8. }

更新数组

以下示例将现有颜色数组替换为新数组(其中包括 Orange)并从颜色列表中删除 White。新的颜色列表的顺序是在 update() 操作中指定的。

  1. db.example.update(
  2. { "Item" : "Poster Paint" },
  3. { $set: { "Colors": ["Red","Green","Blue","Orange","Black"] } }
  4. )

此操作的结果将类似于下文。

  1. {
  2. "Item": "Poster Paint",
  3. "Colors": ["Red","Green","Blue","Orange","Black"],
  4. "Inventory": {
  5. "OnHand": 47,
  6. "MinOnHand": 50
  7. }
  8. }

添加新字段

要通过添加一个或多个新字段修改文档,请使用带有查询文档的 update() 操作,该查询文档使用 $set 运算符标识要插入的文档及新字段和值。

以下示例将值为 3.99 的字段 UnitPrice 添加到 Spray Paints 文档。请注意,值 3.99 是数字,而不是字符串。

  1. db.example.update(
  2. { "Item": "Spray Paint" },
  3. { $set: { "UnitPrice": 3.99 } }
  4. )

此操作的结果将类似于下文(JSON 格式)。

  1. {
  2. "Item": "Spray Paint",
  3. "Colors": ["Black","Red","Green","Blue"],
  4. "Inventory": {
  5. "OnHand": 47,
  6. "MinOnHand": 50,
  7. "OrderQnty": 36
  8. },
  9. "UnitPrice": 3.99
  10. }

替换嵌入文档

要通过替换嵌入文档来修改文档,请将 update() 操作和文档(使用 $set 运算符标识嵌入文档及其新字段和值)结合使用。

给定以下文档。

  1. db.example.insert({
  2. "DocName": "Document 1",
  3. "Date": {
  4. "Year": 1987,
  5. "Month": 4,
  6. "Day": 18
  7. }
  8. })

替换嵌入文档

以下示例将当前 Date 文档替换为新文档,后者仅具有 MonthDay 字段;并且已消除 Year

  1. db.example.update(
  2. { "DocName" : "Document 1" },
  3. { $set: { "Date": { "Month": 4, "Day": 18 } } }
  4. )

此操作的结果将类似于下文。

  1. {
  2. "DocName": "Document 1",
  3. "Date": {
  4. "Month": 4,
  5. "Day": 18
  6. }
  7. }

将新字段插入嵌入文档

将字段添加到嵌入文档

要通过向嵌入文档添加一个或多个新字段来修改文档,请将 update() 操作与文档(标识嵌入文档)结合使用,并使用“点表示法”通过 $set 运算符指定嵌入文档以及要插入的新字段和值。

给定下面的文档,以下代码使用“点表示法”将 YearDoW 字段插入嵌入式 Date 文档中,并将 Words 插入父文档中。

  1. {
  2. "DocName": "Document 1",
  3. "Date": {
  4. "Month": 4,
  5. "Day": 18
  6. }
  7. }
  1. db.example.update(
  2. { "DocName" : "Document 1" },
  3. { $set: { "Date.Year": 1987,
  4. "Date.DoW": "Saturday",
  5. "Words": 2482 } }
  6. )

此操作的结果将类似于下文。

  1. {
  2. "DocName": "Document 1",
  3. "Date": {
  4. "Month": 4,
  5. "Day": 18,
  6. "Year": 1987,
  7. "DoW": "Saturday"
  8. },
  9. "Words": 2482
  10. }

从文档中删除字段

要通过删除文档中的字段来修改文档,请将 update() 操作与查询文档(标识要从中删除字段的文档)和 $unset 运算符(指定要删除的字段)结合使用。

以下示例从前述文档中删除 Words 字段。

  1. db.example.update(
  2. { "DocName" : "Document 1" },
  3. { $unset: { Words:1 } }
  4. )

此操作的结果将类似于下文。

  1. {
  2. "DocName": "Document 1",
  3. "Date": {
  4. "Month": 4,
  5. "Day": 18,
  6. "Year": 1987,
  7. "DoW": "Saturday"
  8. }
  9. }

从多个文档中删除字段

要通过从多个文档中删除字段来修改文档,请使用具有 $unset 运算符和 multi 选项的 update() 操作设置为 true

以下示例从示例集合中的所有文档中删除 Inventory 字段。如果文档没有 Inventory 字段,则不对该文档采取任何操作。如果省略了 multi: true,则仅只在符合标准的第一个文档上执行此操作。

  1. db.example.update(
  2. {},
  3. { $unset: { Inventory:1 } },
  4. { multi: true }
  5. )

删除文档

要从您的数据库删除文档,请使用 remove() 操作,指定要删除哪个文档。以下代码将从 example 集合中删除“Gel Pen”。

  1. db.example.remove( { "Item": "Gel Pen" } )

要删除数据库中的所有文档,请将 remove() 操作和空查询结合使用,如下所示。

  1. db.example.remove( { } )