文件首頁
MySQL 8.4 參考手冊
相關文件 下載本手冊
PDF (美式信紙) - 39.9Mb
PDF (A4) - 40.0Mb
Man Pages (TGZ) - 258.5Kb
Man Pages (Zip) - 365.5Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


22.4.3.3 尋找文件

您可以使用 find() 方法來查詢並傳回架構中集合的文件。MySQL Shell 提供其他方法與 find() 方法搭配使用,以篩選和排序傳回的文件。

MySQL 提供下列運算子來指定搜尋條件:OR (||)、AND (&&)、XORISNOTBETWEENINLIKE!=<>>>=<<=&|<<>>+-*/~%

尋找集合中的所有文件

若要傳回集合中的所有文件,請使用 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 高於 5000 億美元的國家。countryinfo 集合以百萬為單位測量 GNP。

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

下列查詢中的人口欄位內嵌於 demographics 物件內。若要存取內嵌欄位,請在 demographics 和人口之間使用句點來識別關聯性。文件和欄位名稱會區分大小寫。

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

下列運算式中的算術運算子用於查詢人均 GNP 高於 30000 美元的國家。搜尋條件可以包含算術運算子和大多數 MySQL 函數。

注意

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)
提示

在程式中,繫結可讓您在運算式中指定預留位置,這些預留位置會在執行前填入值,並且可以適當地受益於自動跳脫。

務必使用繫結來清理輸入。避免使用字串串連在查詢中引入值,這可能會產生無效的輸入,在某些情況下,可能會導致安全性問題。

您可以使用預留位置和 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() 方法。將要排序的一個或多個欄位清單,以及視情況選用的遞減 (desc) 或遞增 (asc) 屬性傳遞至 sort() 方法。遞增順序是預設順序類型。

例如,下列查詢會依 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)
相關資訊