MySQL 8.0 リファレンスマニュアル


20.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 第12章「関数と演算子 の構文と同じです。 すべての式は引用符で囲む必要があります。 簡潔にするために、一部の例では出力が表示されません。

単純検索条件は、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 が 00 億を超えるすべての国を検索します。 countryinfo コレクションは GNP を百万単位で測定します。

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

次のクエリーの「人口」フィールドは、人口統計オブジェクト内に埋め込まれます。 埋込みフィールドにアクセスするには、人口統計と人口間のピリオドを使用して関係を識別します。 ドキュメント名とフィールド名では大文字と小文字が区別されます。

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

次の式の算術演算子は、大文字当たりの GNP が 0000 を超える国をクエリーするために使用されます。 検索条件には、算術演算子およびほとんどの MySQL 関数を含めることができます。

注記

countryinfo コレクション内の 7 つのドキュメントの母集団値はゼロです。 したがって、出力の最後に警告メッセージが表示されます。

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)

また、返されるドキュメントを記述する式を使用して、返されるドキュメント (追加、名前変更、ネストおよび新しいフィールド値の計算) を変更できます。 たとえば、次の式を使用してフィールドの名前を変更すると、2 つのドキュメントのみが返されます。

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 コレクション内の最初の 5 つのドキュメントを返します。

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

結果の順序を指定するには、sort() メソッドを find() メソッドに追加します。 必要に応じて、降順 (desc) または昇順 (asc) 属性でソートするフィールドのリストを sort() メソッドに渡します。 昇順がデフォルトのオーダータイプです。

たとえば、次のクエリーでは、すべてのドキュメントが IndepYear フィールドでソートされ、最初の 8 つのドキュメントが降順で返されます。

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

デフォルトでは、limit() メソッドはコレクション内の最初のドキュメントから始まります。 skip() メソッドを使用して、開始ドキュメントを変更できます。 たとえば、最初のドキュメントを無視し、条件に一致する次の 8 つのドキュメントを返すには、skip() メソッドに値 1 を渡します。

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

関連キーワード:  ドキュメント, 検索, メソッド, find, コレクション, countryinfo, Name, テーブル, フィールド, 条件