在MySQL中,我们通常不称数据表中的记录为“文档”,而是称之为“行”或“记录”。记录表示为JSON对象。在内部,它们以高效的二进制格式存储,从而实现快速查找和更新。
使用add()方法可以将一个记录或记录列表插入到现有集合中。将以下记录插入countryinfo集合。由于这是多行内容,请按Enter键两次以插入记录。
- mysql-js> db.countryinfo.add(
- {
- GNP: .6,
- IndepYear: 1967,
- Name: "Sealand",
- Code: "SEA",
- demographics: {
- LifeExpectancy: 79,
- Population: 27
- },
- geography: {
- Continent: "Europe",
- Region: "British Islands",
- SurfaceArea: 193
- },
- government: {
- GovernmentForm: "Monarchy",
- HeadOfState: "Michael Bates"
- }
- }
- )
该方法返回操作的状态。您可以通过搜索记录来验证操作。例如
- mysql-js> db.countryinfo.find("Name = 'Sealand'")
- {
- "GNP": 0.6,
- "_id": "00005e2ff4af00000000000000f4",
- "Name": "Sealand",
- "Code:": "SEA",
- "IndepYear": 1967,
- "geography": {
- "Region": "British Islands",
- "Continent": "Europe",
- "SurfaceArea": 193
- },
- "government": {
- "HeadOfState": "Michael Bates",
- "GovernmentForm": "Monarchy"
- },
- "demographics": {
- "Population": 27,
- "LifeExpectancy": 79
- }
- }
除了添加记录时指定的字段外,还有一个字段_id。每个记录都需要一个名为_id的标识符字段。_id字段的值在同一集合中的所有记录中必须是唯一的。在MySQL 8.0.11及更高版本中,记录id是由服务器生成的,而不是由客户端生成的,因此MySQL Shell不会自动设置_id值。如果记录不包含_id字段,则8.0.11或更高版本的MySQL服务器会设置_id值。在这种情况下,8.0版本或5.7版本的MySQL服务器不会设置_id值,因此必须显式指定。如果不这样做,MySQL Shell将返回错误5115记录缺少一个必填字段。
您可以使用find()方法从模式中的集合中查询和返回记录。MySQL Shell提供了额外的方法与find()方法一起使用,以过滤和排序返回的记录。
MySQL提供了以下运算符来指定搜索条件:OR(||)、AND(&&)、XOR、IS、NOT、BETWEEN、IN、LIKE、!=、<>、>、>=、<、<=、&、|、<<、>>、+、-、*、/、~、和 %。
若要返回集合中的所有记录,请使用find()方法,而不指定搜索条件。例如,以下操作将返回countryinfo集合中的所有记录。
- mysql-js> db.countryinfo.find()
- [
- {
- "GNP": 828,
- "Code:": "ABW",
- "Name": "Aruba",
- "IndepYear": null,
- "geography": {
- "Continent": "North America",
- "Region": "Caribbean",
- "SurfaceArea": 193
- },
- "government": {
- "GovernmentForm": "Nonmetropolitan Territory of The Netherlands",
- "HeadOfState": "Beatrix"
- }
- "demographics": {
- "LifeExpectancy": 78.4000015258789,
- "Population": 103000
- },
- ...
- }
- ]
- 240 documents in set (0.00 sec)
该方法生成的结果除了包含集合中的所有记录之外,还包含操作信息。
空集(没有匹配的记录)返回以下信息:
Empty set (0.00 sec)
您可以使用find()方法包含搜索条件。所有表达式都必须用引号括起来。为了简洁起见,有些示例不显示输出。
一个简单的搜索条件可以由Name字段和一个我们知道在记录中的值组成。以下示例返回单个记录:
- mysql-js> db.countryinfo.find("Name = 'Australia'")
- [
- {
- "GNP": 351182,
- "Code:": "AUS",
- "Name": "Australia",
- "IndepYear": 1901,
- "geography": {
- "Continent": "Oceania",
- "Region": "Australia and New Zealand",
- "SurfaceArea": 7741220
- },
- "government": {
- "GovernmentForm": "Constitutional Monarchy, Federation",
- "HeadOfState": "Elisabeth II"
- }
- "demographics": {
- "LifeExpectancy": 79.80000305175781,
- "Population": 18886000
- },
- }
- ]
以下示例搜索所有国民生产总值高于5000亿美元的国家。国家信息收集以百万为单位衡量国民生产总值。
- mysql-js> db.countryinfo.find("GNP > 500000")
- ...[output removed]
- 10 documents in set (0.00 sec)
以下查询中的“人口”字段嵌入到人口统计对象中。要访问嵌入的字段,请使用人口统计和人口统计之间的时间段来确定关系。记录和字段名称区分大小写。
- mysql-js> db.countryinfo.find("GNP > 500000 and demographics.Population < 100000000")
- ...[output removed]
- 6 documents in set (0.00 sec)
以下表达式中的算术运算符用于查询人均国民生产总值高于30000美元的国家。搜索条件可以包括算术运算符和大多数MySQL函数。
注意:countryinfo集合中有七个记录的总体值为零。因此,警告消息会出现在输出的末尾。
- mysql-js> db.countryinfo.find("GNP*1000000/demographics.Population > 30000")
- ...[output removed]
- 9 documents in set, 7 warnings (0.00 sec)
- Warning (Code 1365): Division by 0
- Warning (Code 1365): Division by 0
- Warning (Code 1365): Division by 0
- Warning (Code 1365): Division by 0
- Warning (Code 1365): Division by 0
- Warning (Code 1365): Division by 0
- Warning (Code 1365): Division by 0
可以使用bind()方法将值与搜索条件分离。例如,不要指定硬编码的国家/地区名称作为条件,而是替换一个由冒号和以字母开头的名称(如国家/地区)组成的命名占位符。然后使用bind(占位符,value)方法,如下所示:
- mysql-js> db.countryinfo.find("Name = :country").bind("country", "Italy")
- {
- "GNP": 1161755,
- "_id": "00005de917d8000000000000006a",
- "Code": "ITA",
- "Name": "Italy",
- "Airports": [],
- "IndepYear": 1861,
- "geography": {
- "Region": "Southern Europe",
- "Continent": "Europe",
- "SurfaceArea": 301316
- },
- "government": {
- "HeadOfState": "Carlo Azeglio Ciampi",
- "GovernmentForm": "Republic"
- },
- "demographics": {
- "Population": 57680000,
- "LifeExpectancy": 79
- }
- }
- 1 document in set (0.01 sec)
在程序中,绑定使您能够在表达式中指定占位符,这些占位符在执行前用值填充,并且可以从自动转义中受益(视情况而定)。
始终使用绑定对输入进行清理。避免在使用字符串串联的查询中引入值,这可能会产生无效输入,在某些情况下还会导致安全问题。
您可以使用占位符和bind()方法创建保存的搜索,然后使用不同的值调用这些搜索。例如,要创建已保存的国家/地区搜索:
- mysql-js> var myFind = db.countryinfo.find("Name = :country")
- mysql-js> myFind.bind('country', 'France')
- {
- "GNP": 1424285,
- "_id": "00005de917d80000000000000048",
- "Code": "FRA",
- "Name": "France",
- "IndepYear": 843,
- "geography": {
- "Region": "Western Europe",
- "Continent": "Europe",
- "SurfaceArea": 551500
- },
- "government": {
- "HeadOfState": "Jacques Chirac",
- "GovernmentForm": "Republic"
- },
- "demographics": {
- "Population": 59225700,
- "LifeExpectancy": 78.80000305175781
- }
- }
- 1 document in set (0.0028 sec)
-
- mysql-js> myFind.bind('country', 'Germany')
- {
- "GNP": 2133367,
- "_id": "00005de917d80000000000000038",
- "Code": "DEU",
- "Name": "Germany",
- "IndepYear": 1955,
- "geography": {
- "Region": "Western Europe",
- "Continent": "Europe",
- "SurfaceArea": 357022
- },
- "government": {
- "HeadOfState": "Johannes Rau",
- "GovernmentForm": "Federal Republic"
- },
- "demographics": {
- "Population": 82164700,
- "LifeExpectancy": 77.4000015258789
- }
- }
-
- 1 document in set (0.0026 sec)
您可以返回记录的特定字段,而不是返回所有字段。以下示例返回countryinfo集合中与搜索条件匹配的所有记录的GNP和Name字段。
使用fields()方法传递要返回的字段列表。
- mysql-js> db.countryinfo.find("GNP > 5000000").fields(["GNP", "Name"])
- [
- {
- "GNP": 8510700,
- "Name": "United States"
- }
- ]
- 1 document in set (0.00 sec)
此外,还可以通过表达式来描述想要返回的记录,并对这些返回的记录进行修改,比如添加、重命名、嵌套字段,甚至计算新的字段值。
例如,使用以下表达式更改字段的名称以仅返回两个记录。
- mysql-js> db.countryinfo.find().fields(
- mysqlx.expr('{"Name": upper(Name), "GNPPerCapita": GNP*1000000/demographics.Population}')).limit(2)
- {
- "Name": "ARUBA",
- "GNPPerCapita": 8038.834951456311
- }
- {
- "Name": "AFGHANISTAN",
- "GNPPerCapita": 263.0281690140845
- }
您可以应用limit()、sort()和skip()方法来管理find()方法返回的记录的数量和顺序。
要指定结果集中包含的记录数,请在find()方法后面附加一个值的limit()方法。以下查询返回countryinfo集合中的前五个记录。
- mysql-js> db.countryinfo.find().limit(5)
- ... [output removed]
- 5 documents in set (0.00 sec)
若要对查询结果进行排序,可以在find()
方法后附加sort()
方法。你需要向sort()
方法传递一个或多个字段名称的列表,用以指明排序的依据。同时,你还可以选择性地为每个字段指定排序方式,即升序(asc
)或降序(desc
)。若未明确指定,则默认采用升序排序。
例如,以下查询按IndepYear字段对所有记录进行排序,然后按降序返回前八个记录。
- mysql-js> db.countryinfo.find().sort(["IndepYear desc"]).limit(8)
- ... [output removed]
- 8 documents in set (0.00 sec)
limit()
方法默认从集合中的第一个记录开始返回结果。如果你想改变起始的记录,可以使用skip()
方法。例如,如果你想忽略第一个记录,并返回接下来符合条件的八个记录,你可以将1
作为参数传递给skip()
方法。
- mysql-js> db.countryinfo.find().sort(["IndepYear desc"]).limit(8).skip(1)
- ... [output removed]
- 8 documents in set (0.00 sec)