MySQL 文档与集合

文档和集合
在MySQL中,集合包含JSON文档,你可以添加、查找、更新和删除这些文档。集合是模式中的容器,可以创建、列出和删除。

文档
在MySQL中,文档表示为JSON对象。在内部,它们以高效的二进制格式存储,支持快速查找和更新。
.JavaScript的简单文档格式:

{field1: "value", field2 : 10, "field 3": null}

文档数组由一组用逗号分隔、用[和]字符包裹的文档组成。

[{Name: "Aruba", _id: "ABW"}, {Name: "Angola", _id: "AGO"}]

MySQL支持JSON文档中的以下JavaScript值类型:
.数字(整数和浮点数)
.字符串
.布尔值(false和true)
.null
.包含更多JSON值的数组
.具有更多JSON值的嵌套(或嵌入)对象

集合
集合是用于共享目的的文档的容器,并且可能共享一个或多个索引。每个集合都有唯一的名称,并且存在于单一的模式中。
术语模式等同于数据库,意味着一组数据库对象(与之相对的是用于强制数据的结构和约束的关系模式)。模式并不强制集合中的文档保持一致性。基本对象包括:
.db:
db是一个全局变量,该变量分配给您在命令行上指定的当前活动模式。你可以在MySQL Shell中输入db来打印对象的描述,在本例中就是它所代表的模式的名称。

.db.getCollections():db.getCollections()保存了模式中的集合列表。使用列表获取集合对象的引用,迭代它们,等等。

集合作用域的基本操作包括:
.db.name.add():add()方法将一个文档或一个文档列表插入到指定的集合中。
.db.name.find():find()方法返回指定集合中的部分或全部文档。
.db.name.modify():方法modify()更新指定集合中的文档。
.db.name.remove():remove()方法从指定集合中删除一个文档或一个文档列表。

创建、显示和删除集合
在MySQL Shell中,你可以创建新的集合,获取模式中已存在集合的列表,或者从模式中删除已存在的集合。集合名称区分大小写,每个集合名称必须唯一。
确认模式
要显示分配给模式变量的值,请输入db。

 MySQL  localhost:33060+  world_x  JS > db

 MySQL  localhost:33060+  world_x  JS > 

如果schema值不是schema:world_x,则设置db变量如下:

 MySQL  localhost:33060+  JS > db
 MySQL  localhost:33060+  JS > \use world_x
Default schema `world_x` accessible through db.
 MySQL  localhost:33060+  world_x  JS > db

 MySQL  localhost:33060+  world_x  JS > 

创建一个集合
要在现有模式中创建新集合,可以使用createCollection()方法。下面的示例在world_x数据库中创建一个名为flags的集合。该方法返回一个集合对象。

 MySQL  localhost:33060+  world_x  JS > db.createCollection("flags")

 MySQL  localhost:33060+  world_x  JS > 

显示集合
要显示world_x数据库中的所有集合,可以在schema对象上使用getCollections()方法。服务器返回的集合出现在括号中。

 MySQL  localhost:33060+  world_x  JS > db.getCollections()
[
    
]
 MySQL  localhost:33060+  world_x  JS > 

删除集合
要从数据库中删除已有的集合,可以在session对象上调用dropCollection()方法。例如,要从world_x数据库中删除flags集合,输入:

 MySQL  localhost:33060+  world_x  JS > db.dropCollection("flags")
 MySQL  localhost:33060+  world_x  JS > db.getCollections()
[]

添加文档
使用MySQL Shell,可以使用add()方法将一个文档或一个列表文档插入到现有的集合中。本节中的所有示例都使用flags集合。
确认模式
要显示分配给模式变量的值,请输入db。

 MySQL  localhost:33060+  world_x  JS > db

如果schema值不是schema:world_x,则设置db变量如下:

 MySQL  localhost:33060+  JS > db
 MySQL  localhost:33060+  JS > \use world_x
Default schema `world_x` accessible through db.

添加文档
将下面的文档插入flags集合。按两次Enter键插入文档。

  MySQL  localhost:33060+  world_x  JS > db.createCollection("flags")


mysql> desc flags
    -> ;
+-------+-------------+------+-----+---------+------------------+
| Field | Type        | Null | Key | Default | Extra            |
+-------+-------------+------+-----+---------+------------------+
| doc   | json        | YES  |     | NULL    |                  |
| _id   | varchar(32) | NO   | PRI | NULL    | STORED GENERATED |
+-------+-------------+------+-----+---------+------------------+
2 rows in set (0.00 sec)



 MySQL  localhost:33060+  world_x  JS > db.getCollections()
[
    
]
 MySQL  localhost:33060+  world_x  JS >  db.flags.add(
                                     ->  {
                                     ->   GNP: .6,
                                     ->   IndepYear: 1967,
                                     ->   Name: "Sealand",
                                     ->   _id: "SEA",
                                     ->   demographics: {
                                     ->       LifeExpectancy: 79,
                                     ->       Population: 27
                                     ->   },
                                     ->   geography: {
                                     ->       Continent: "Europe",
                                     ->       Region: "British Islands",
                                     ->       SurfaceArea: 193
                                     ->   },
                                     ->   government: {
                                     ->       GovernmentForm: "Monarchy",
                                     ->       HeadOfState: "Michael Bates"
                                     ->   }
                                     ->  }
                                     -> )
                                     -> 
Query OK, 1 item affected (0.0073 sec)
 MySQL  localhost:33060+  world_x  JS > 

该方法返回操作的状态。

每个文档都需要一个名为_id的标识符字段。_id字段的值必须在同一个集合中的所有文档中唯一。如果传递给add()方法的文档不包含_id字段
,MySQL Shell会自动在文档中插入一个字段,并设置该字段的值为生成的UUID (universal unique identifier,通用唯一标识符)。

查找文档
可以使用find()方法从数据库中的集合中查询并返回文档。MySQL Shell为find()方法提供了额外的方法来过滤和排序返回的文档。
MySQL提供了以下运营商指定搜索条件:OR (||), AND (&&), XOR, IS, NOT,BETWEEN, IN, LIKE, !=, <>, >, >=, < , <=, &, |, <<, >>, +, -, *, /, ~, 和 %.

查找集合中的所有文档
要返回集合中的所有文档,可以使用find()方法,但不指定搜索条件。例如,下面的操作返回flags集合中的所有文档。

Query OK, 1 item affected (0.0154 sec)
 MySQL  localhost:33060+  world_x  JS > db.flags.find();
{
    "GNP": 351182,
    "_id": "AUS",
    "Name": "Australia",
    "IndepYear": 1901,
    "geography": {
        "Region": "Australia and New Zealand",
        "Continent": "Oceania",
        "SurfaceArea": 7741220
    },
    "government": {
        "HeadOfState": "Elisabeth II",
        "GovernmentForm": "Constitutional Monarchy, Federation"
    },
    "demographics": {
        "Population": 18886000,
        "LifeExpectancy": 79.80000305175781
    }
}
{
    "GNP": 0.6,
    "_id": "SEA",
    "Name": "Sealand",
    "IndepYear": 1967,
    "geography": {
        "Region": "British Islands",
        "Continent": "Europe",
        "SurfaceArea": 193
    },
    "government": {
        "HeadOfState": "Michael Bates",
        "GovernmentForm": "Monarchy"
    },
    "demographics": {
        "Population": 27,
        "LifeExpectancy": 79
    }
}
2 documents in set (0.0009 sec)

该方法生成的结果除了包含集合中的所有文档外,还包含操作信息。
一个空集合(没有匹配的文档)返回以下信息:

Empty set (0.00 sec)

过滤搜索
你可以在find()方法中包含搜索条件。组成搜索条件的表达式的语法与传统MySQL相同。所有表达式必须用引号括起来。
本节中的所有示例都使用world_x数据库中的flags集合。为简洁起见,有些示例不显示输出。
一个简单的搜索条件由_id字段和文档的唯一标识符组成。下面的例子返回一个与标识符字符串匹配的文档:

 MySQL  localhost:33060+  world_x  JS > db.flags.find("_id = 'SEA'")
{
    "GNP": 0.6,
    "_id": "SEA",
    "Name": "Sealand",
    "IndepYear": 1967,
    "geography": {
        "Region": "British Islands",
        "Continent": "Europe",
        "SurfaceArea": 193
    },
    "government": {
        "HeadOfState": "Michael Bates",
        "GovernmentForm": "Monarchy"
    },
    "demographics": {
        "Population": 27,
        "LifeExpectancy": 79
    }
}
1 document in set (0.0023 sec)
 MySQL  localhost:33060+  world_x  JS > 

下面的示例搜索GNP高于3000亿美元的所有国家。国家信息收集以百万为单位衡量国民生产总值。

 MySQL  localhost:33060+  world_x  JS > db.flags.find("GNP > 300000");
{
    "GNP": 351182,
    "_id": "AUS",
    "Name": "Australia",
    "IndepYear": 1901,
    "geography": {
        "Region": "Australia and New Zealand",
        "Continent": "Oceania",
        "SurfaceArea": 7741220
    },
    "government": {
        "HeadOfState": "Elisabeth II",
        "GovernmentForm": "Constitutional Monarchy, Federation"
    },
    "demographics": {
        "Population": 18886000,
        "LifeExpectancy": 79.80000305175781
    }
}
1 document in set (0.0012 sec)

下面查询中的Population字段嵌入到人口统计对象中。要访问嵌入式字段,使用人口统计数据和人口之间的句号来识别关系。文档名和字段名区分大小写。

 MySQL  localhost:33060+  world_x  JS > db.flags.find("GNP > 300000 and demographics.Population <100000000")
{
    "GNP": 351182,
    "_id": "AUS",
    "Name": "Australia",
    "IndepYear": 1901,
    "geography": {
        "Region": "Australia and New Zealand",
        "Continent": "Oceania",
        "SurfaceArea": 7741220
    },
    "government": {
        "HeadOfState": "Elisabeth II",
        "GovernmentForm": "Constitutional Monarchy, Federation"
    },
    "demographics": {
        "Population": 18886000,
        "LifeExpectancy": 79.80000305175781
    }
}
1 document in set (0.0012 sec)

可以使用bind()方法将值与搜索条件分开。例如,与其指定硬编码的国家名作为条件,不如用冒号和以字母开头的名称(如country)组成的命名占位符。然后在bind()方法中包含占位符和值,如下所示:

 MySQL  localhost:33060+  world_x  JS > db.flags.find("Name = :country").bind("country", "Sealand")
{
    "GNP": 0.6,
    "_id": "SEA",
    "Name": "Sealand",
    "IndepYear": 1967,
    "geography": {
        "Region": "British Islands",
        "Continent": "Europe",
        "SurfaceArea": 193
    },
    "government": {
        "HeadOfState": "Michael Bates",
        "GovernmentForm": "Monarchy"
    },
    "demographics": {
        "Population": 27,
        "LifeExpectancy": 79
    }
}
1 document in set (0.0059 sec)

在程序中,绑定使您能够在表达式中指定占位符,这些占位符在执行之前被填充值,并且可以根据需要从自动转义中获益。始终使用绑定来清理输入。使用字符串连接避免在查询中引入值,这会产生无效的输入,在某些情况下,可能会导致安全问题。
可以返回文档的特定字段,而不是返回所有字段。下面的示例返回flags集合中匹配搜索条件的所有文档的GNP和Name字段。
使用fields()方法传递要返回的字段列表

 MySQL  localhost:33060+  world_x  JS > db.flags.find("GNP > 300000").fields(["GNP","Name"])
{
    "GNP": 351182,
    "Name": "Australia"
}
1 document in set (0.0017 sec)

此外,您可以使用描述要返回的文档的表达式来更改返回的文档——添加、重命名、嵌套甚至计算新的字段值。例如,使用下面的表达式更改字段的名称,使其仅返回两个文档。

 MySQL  localhost:33060+  world_x  JS > db.flags.find().fields(mysqlx.expr('{"Name": upper(Name), "GNPPerCapita": 

GNP*1000000/demographics.Population}')).limit(2)
{
    "Name": "AUSTRALIA",
    "GNPPerCapita": 18594.832150799535
}
{
    "Name": "SEALAND",
    "GNPPerCapita": 22222.222222222223
}
2 documents in set (0.0019 sec)

限制、排序和跳过结果
可以应用limit()、sort()和skip()方法来管理find()方法返回的文档数量和顺序。
要指定结果集中包含的文档数量,请将带有值的limit()方法附加到find()方法。下面的查询返回flags集合中的第一个文档。

 MySQL  localhost:33060+  world_x  JS > db.flags.find().limit(1)
{
    "GNP": 351182,
    "_id": "AUS",
    "Name": "Australia",
    "IndepYear": 1901,
    "geography": {
        "Region": "Australia and New Zealand",
        "Continent": "Oceania",
        "SurfaceArea": 7741220
    },
    "government": {
        "HeadOfState": "Elisabeth II",
        "GovernmentForm": "Constitutional Monarchy, Federation"
    },
    "demographics": {
        "Population": 18886000,
        "LifeExpectancy": 79.80000305175781
    }
}
1 document in set (0.0031 sec)

要指定结果的顺序,请将sort()方法附加到find()方法后。将一个或多个要排序的字段的列表传递给sort()方法,并根据需要可选地传递降序(desc)或升序(asc)属性。升序是默认的顺序类型。
例如,下面的查询按IndepYear字段对所有文档进行排序,然后按降序返回前2个文档。

 MySQL  localhost:33060+  world_x  JS > db.flags.find().sort(["IndepYear desc"]).limit(2)
{
    "GNP": 0.6,
    "_id": "SEA",
    "Name": "Sealand",
    "IndepYear": 1967,
    "geography": {
        "Region": "British Islands",
        "Continent": "Europe",
        "SurfaceArea": 193
    },
    "government": {
        "HeadOfState": "Michael Bates",
        "GovernmentForm": "Monarchy"
    },
    "demographics": {
        "Population": 27,
        "LifeExpectancy": 79
    }
}
{
    "GNP": 351182,
    "_id": "AUS",
    "Name": "Australia",
    "IndepYear": 1901,
    "geography": {
        "Region": "Australia and New Zealand",
        "Continent": "Oceania",
        "SurfaceArea": 7741220
    },
    "government": {
        "HeadOfState": "Elisabeth II",
        "GovernmentForm": "Constitutional Monarchy, Federation"
    },
    "demographics": {
        "Population": 18886000,
        "LifeExpectancy": 79.80000305175781
    }
}
2 documents in set (0.0032 sec)

默认情况下,limit()方法从集合中的第一个文档开始。您可以使用skip()方法来更改起始文档。例如,要忽略第一个文档并返回后面1个匹配条件的文档,可以将值1传递给skip()方法。

 MySQL  localhost:33060+  world_x  JS > db.flags.find().sort(["IndepYear desc"]).limit(1).skip(1)
{
    "GNP": 351182,
    "_id": "AUS",
    "Name": "Australia",
    "IndepYear": 1901,
    "geography": {
        "Region": "Australia and New Zealand",
        "Continent": "Oceania",
        "SurfaceArea": 7741220
    },
    "government": {
        "HeadOfState": "Elisabeth II",
        "GovernmentForm": "Constitutional Monarchy, Federation"
    },
    "demographics": {
        "Population": 18886000,
        "LifeExpectancy": 79.80000305175781
    }
}
1 document in set (0.0015 sec)

修改文档
可以使用modify()方法更新集合中的一个或多个文档。X DevAPI提供了与modify()方法一起使用的附加方法:
.设置和取消设置文档中的字段。
.追加、插入和删除数组。
.对要修改的文档进行绑定、限制和排序。

设置和取消设置文档中的字段
modify()方法的工作原理是过滤一个集合,使其只包含要修改的文档,然后将您指定的操作应用于这些文档。
在下面的示例中,modify()方法使用搜索条件来标识要更改的文档,然后set()方法替换嵌套的人口统计对象中的两个值。

 MySQL  localhost:33060+  world_x  JS > db.flags.modify("_id = 'SEA'").set("demographics", {LifeExpectancy: 78, Population: 

28})
Query OK, 1 item affected (0.0333 sec)

Rows matched: 1  Changed: 1  Warnings: 0

在修改文档之后,使用find()方法来验证更改。

 MySQL  localhost:33060+  world_x  JS > db.flags.find("_id = 'SEA'")
{
    "GNP": 0.6,
    "_id": "SEA",
    "Name": "Sealand",
    "IndepYear": 1967,
    "geography": {
        "Region": "British Islands",
        "Continent": "Europe",
        "SurfaceArea": 193
    },
    "government": {
        "HeadOfState": "Michael Bates",
        "GovernmentForm": "Monarchy"
    },
    "demographics": {
        "Population": 28,
        "LifeExpectancy": 78
    }
}
1 document in set (0.0010 sec)

要从文档中删除内容,请使用modify()和unset()方法。例如,下面的查询从匹配搜索条件的文档中删除GNP。

 MySQL  localhost:33060+  world_x  JS > db.flags.modify("Name = 'Sealand'").unset("GNP")
Query OK, 1 item affected (0.0072 sec)

Rows matched: 1  Changed: 1  Warnings: 0

使用find()方法验证更改。

 MySQL  localhost:33060+  world_x  JS > db.flags.find("Name = 'Sealand'")
{
    "_id": "SEA",
    "Name": "Sealand",
    "IndepYear": 1967,
    "geography": {
        "Region": "British Islands",
        "Continent": "Europe",
        "SurfaceArea": 193
    },
    "government": {
        "HeadOfState": "Michael Bates",
        "GovernmentForm": "Monarchy"
    },
    "demographics": {
        "Population": 28,
        "LifeExpectancy": 78
    }
}
1 document in set (0.0010 sec)

追加、插入和删除数组
使用arrayAppend()、arrayInsert()或arrayDelete()方法向数组字段添加元素,或在数组中插入或删除元素。下面的示例修改了flags集合,以启用对国际机场的跟踪。
第一个示例使用modify()和set()方法在所有文档中创建一个新的Airports字段。
在不指定搜索条件的情况下修改文档时要小心。此操作将修改集合中的所有文档。

 MySQL  localhost:33060+  world_x  JS > db.flags.modify("true").set("Airports", [])
Query OK, 3 items affected (0.0071 sec)

Rows matched: 3  Changed: 3  Warnings: 0

添加了Airports字段后,下一个示例将使用arrayAppend()方法向其中一个文档添加一个新机场。美元。下面示例中的Airports表示当前文档的Airports字段。

 MySQL  localhost:33060+  world_x  JS > db.flags.modify("Name = 'France'").arrayAppend("$.Airports", "ORY")
Query OK, 1 item affected (0.0069 sec)

Rows matched: 1  Changed: 1  Warnings: 0

使用db.flags.find”Name = ‘France'”)查看更改。

 MySQL  localhost:33060+  world_x  JS > db.flags.find("Name = 'France'")
{
    "GNP": 5000000,
    "_id": "FRA",
    "Name": "France",
    "Airports": [
        "ORY"
    ],
    "IndepYear": 1967,
    "geography": {
        "Region": "British Islands",
        "Continent": "Europe",
        "SurfaceArea": 193
    },
    "government": {
        "HeadOfState": "Michael Bates",
        "GovernmentForm": "Monarchy"
    },
    "demographics": {
        "Population": 27,
        "LifeExpectancy": 79
    }
}
1 document in set (0.0013 sec)

要在数组的不同位置插入元素,可以使用arrayInsert()方法在路径表达式中指定要插入的索引。在这个例子中,索引是0,即数组的第一个元素。

 MySQL  localhost:33060+  world_x  JS > db.flags.modify("Name = 'France'").arrayInsert("$.Airports[0]", "CDG")
Query OK, 1 item affected (0.0078 sec)

Rows matched: 1  Changed: 1  Warnings: 0
 MySQL  localhost:33060+  world_x  JS > db.flags.find("Name = 'France'")
{
    "GNP": 5000000,
    "_id": "FRA",
    "Name": "France",
    "Airports": [
        "CDG",
        "ORY"
    ],
    "IndepYear": 1967,
    "geography": {
        "Region": "British Islands",
        "Continent": "Europe",
        "SurfaceArea": 193
    },
    "government": {
        "HeadOfState": "Michael Bates",
        "GovernmentForm": "Monarchy"
    },
    "demographics": {
        "Population": 27,
        "LifeExpectancy": 79
    }
}
1 document in set (0.0010 sec)

要从数组中删除一个元素,必须将要删除的元素的索引传递给arrayDelete()方法。

 MySQL  localhost:33060+  world_x  JS > db.flags.modify("Name = 'France'").arrayDelete("$.Airports[1]")
Query OK, 1 item affected (0.0057 sec)

Rows matched: 1  Changed: 1  Warnings: 0
 MySQL  localhost:33060+  world_x  JS > db.flags.find("Name = 'France'")
{
    "GNP": 5000000,
    "_id": "FRA",
    "Name": "France",
    "Airports": [
        "CDG"
    ],
    "IndepYear": 1967,
    "geography": {
        "Region": "British Islands",
        "Continent": "Europe",
        "SurfaceArea": 193
    },
    "government": {
        "HeadOfState": "Michael Bates",
        "GovernmentForm": "Monarchy"
    },
    "demographics": {
        "Population": 27,
        "LifeExpectancy": 79
    }
}
1 document in set (0.0009 sec)

删除文档
可以使用remove()方法从数据库集合中删除部分或全部文档。X DevAPI为remove()方法提供了额外的方法,用于过滤和排序要删除的文档。

使用条件删除文档
下面的例子向remove()方法传递了一个搜索条件。所有符合条件的文档都将从countryinfo集合中删除。在这个例子中,有一个文档符合条件。

 MySQL  localhost:33060+  world_x  JS > db.flags.remove("_id = 'SEA'")
Query OK, 1 item affected (0.0159 sec)

删除第一个文档
要删除flags集合中的第一个文档,可使用limit()方法,将值设为1。

 MySQL  localhost:33060+  world_x  JS > db.flags.remove("true").limit(1)
Query OK, 1 item affected (0.0058 sec)

按顺序删除最后一个文档
下面的示例按国家名删除countryinfo集合中的最后一个文档。

 MySQL  localhost:33060+  world_x  JS > db.flags.remove("true").sort(["Name desc"]).limit(1)
Query OK, 1 item affected (0.02 sec)

删除集合中的所有文档
可以删除集合中的所有文档。为此,可以使用remove(”true”)方法,但不指定任何搜索条件。

 MySQL  localhost:33060+  world_x  JS > db.flags.remove("true");
Query OK, 1 item affected (0.0063 sec)

发表评论

电子邮件地址不会被公开。