Documentation Home
MySQL 8.3 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 40.8Mb
PDF (A4) - 40.9Mb
Man Pages (TGZ) - 294.0Kb
Man Pages (Zip) - 409.0Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb
Excerpts from this Manual

22.4.3.3 查找文档

您可以使用 find() 方法来查询和返回集合中的文档。 MySQL Shell 提供了附加方法来与 find() 方法一起使用,以过滤和排序返回的文档。

MySQL 提供了以下运算符来指定搜索条件:OR (||), AND (&&), XOR, IS, NOT, BETWEEN, IN, LIKE, !=, <>, >, >=, <, <=, &, |, <<, >>, +, -, *, /, ~, 和 %

在集合中查找所有文档

要返回集合中的所有文档,请使用 find() 方法,不指定搜索条件。例如,以下操作将返回 countryinfo 集合中的所有文档。

mysql-py> 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() 方法中包含搜索条件。表达式的语法与传统 MySQL 第 14 章 函数和操作符相同。您必须将所有表达式括在引号中。出于简洁起见,一些示例不显示输出。

简单的搜索条件可能包括 Name 字段和我们知道在文档中的值。以下示例返回单个文档:

mysql-py> 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
        },
    }
]

以下示例搜索所有 GNP 高于 500 亿美元的国家。countryinfo 集合以百万为单位测量 GNP。

mysql-py> db.countryinfo.find("GNP > 500000")
...[output removed]
10 documents in set (0.00 sec)

人口字段在以下查询中嵌入在 demographics 对象中。要访问嵌入字段,请使用句点之间的 demographics 和 Population 来标识关系。文档和字段名称区分大小写。

mysql-py> db.countryinfo.find("GNP > 500000 and demographics.Population < 100000000")
...[output removed]
6 documents in set (0.00 sec)

算术运算符在以下表达式中用于查询 GNP 人均高于 30000 的国家。搜索条件可以包括算术运算符和大多数 MySQL 函数。

Note

countryinfo 集合中的七个文档具有零人口值。因此,在输出的末尾出现警告消息。

mysql-py> 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() 方法将值与搜索条件分离。例如,而不是指定硬编码的国家名称作为条件,使用带有冒号的命名占位符,例如 country。然后使用 bind(placeholder, value) 方法如下:

mysql-py> 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)
Tip

在程序中,绑定使您可以在表达式中指定占位符,然后在执行前填充值,并可以从自动转义中受益。

始终使用绑定来清洁输入。避免使用字符串连接来引入值,以免产生无效的输入和可能的安全问题。

您可以使用占位符和 bind() 方法创建保存的搜索,然后使用不同的值调用它们。例如,要创建一个国家的保存搜索:

mysql-py> myFind = db.countryinfo.find("Name = :country")
mysql-py> 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-py> 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-py> db.countryinfo.find("GNP > 5000000").fields(["GNP", "Name"])
[
    {
        "GNP": 8510700,
        "Name": "United States"
    }
]
1 document in set (0.00 sec)

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

mysql-py> 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() 方法返回的文档数量和顺序。

要指定结果集中的文档数量,请将 limit() 方法附加到 find() 方法,并传递一个值。以下查询返回 countryinfo 集合中的前五个文档。

mysql-py> db.countryinfo.find().limit(5)
... [output removed]
5 documents in set (0.00 sec)

要指定结果的顺序,请将 sort() 方法附加到 find() 方法。将一个或多个字段的列表传递给 sort() 方法,并可选地指定降序 (desc) 或升序 (asc) 属性。升序是默认的顺序类型。

例如,以下查询按 IndepYear 字段对所有文档进行排序,然后以降序返回前八个文档。

mysql-py> db.countryinfo.find().sort(["IndepYear desc"]).limit(8)
... [output removed]
8 documents in set (0.00 sec)

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

mysql-py> db.countryinfo.find().sort(["IndepYear desc"]).limit(8).skip(1)
... [output removed]
8 documents in set (0.00 sec)
相关信息
  • MySQL 参考手册提供了函数和操作符的详细文档。

  • 请参阅 CollectionFindFunction 以获取完整的语法定义。