ここは旧式の4DドキュメントWebサイトです。最新のアップデートされたドキュメントを読むには新サイトをご利用下さい→ developer.4d.com |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
4D v19.8
dataClass.query( )
|
dataClass.query ( queryString | formula {; value}{; value2 ; ... ; valueN}{; querySettings}) -> 戻り値 | ||||||||
引数 | 型 | 説明 | ||||||
queryString | formula | テキスト, オブジェクト |
![]() |
検索条件 (テキストまたはフォーミュラーオブジェクト) | |||||
value | Mixed |
![]() |
インデックスプレースホルダーを使用する場合の比較する値 | |||||
querySettings | オブジェクト |
![]() |
クエリオプション: parameters, attributes, args, allowFormulas, context, queryPath, queryPlan | |||||
戻り値 | EntitySelection |
![]() |
データクラス内の、queryStringで指定した検索条件に合致するエンティティから構成された新しいエンティティセレクション | |||||
dataClass.query( ) メソッドは、データクラス内にある全てのエンティティから、queryString または formula 引数と任意のvalue 引数で指定された検索条件に合致するエンティティを検索し、データクラス内から見つかった全てのエンティティを格納するEntitySelection 型の新しいオブジェクトを返します。このメソッドにはレイジーローディングが適用されます。
合致するエンティティが見つからない場合、空のEntitySelection が返されます。
queryString 引数は以下のシンタックスを使用します:
attributePath|formula comparator value {logicalOperator attributePath|formula comparator value} {order by attributePath {desc | asc}}
詳細は以下の通りです:
"eval(length(This.lastname) >=30)"
(*) フォーミュラ以外にも検索条件がある場合、クエリエンジンの最適化によってほかの検索条件(例えばインデックス属性)の処理が優先される場合があり、その場合はエンティティのサブセットのみフォーミュラの評価対象となります。
クエリに使用するフォーミュラは$1を介して引数を受け取ることができます。詳細については後述の フォーミュラ引数 を参照ください。
注:
- フォーミュラが複雑な場合など、queryString パラメーターを使わずに、formula パラメーターオブジェクトを直接渡すこともできます。後述の フォーミュラ引数 を参照ください。
- セキュリティのため、query() メンバーメソッド内のフォーミュラ使用を禁止することができます。querySettings パラメーターの説明を参照ください。
比較 | 記号 | 補足 |
等しい | =, == | 一致するデータを取得。ワイルドカード(@)をサポートし、大文字小文字/アクセント記号の有無は区別しません。 |
===, IS | 一致するデータを取得。ワイルドカード(@)は標準文字として認識され、大文字小文字/アクセント記号の有無は区別しません。 | |
等しくない | #, != | ワイルドカード(@)をサポート |
!==, IS NOT | ワイルドカード(@)は標準文字として認識 | |
未満 | < | |
より大きい | > | |
以下 | <= | |
以上 | >= | |
含まれる | IN | コレクション、あるいは複数の値の中の、どれか一つの値と等しいデータを取得します。ワイルドカード(@)をサポート |
宣言にNot 条件を適用する | NOT | 複数の演算子が含まれる宣言の前にNOTを使用する場合にはカッコをつける必要があります。 |
キーワードを含む | % | キーワードは文字列あるいはピクチャー型の属性中で使用されるものが対象です |
結合 | 記号 |
AND | &, &&, and |
OR | |, ||, or |
クオートを使用する
クエリ内でクオートを使用する場合、クエリ内においてはシングルクオート ' 'を使用し、クエリ全体をくくるためにはダブルクオート " " を使用します。クオートを混同するとエラーが返されます。例:
"employee.name = 'smith' AND employee.firstname = 'john'"
注: シングルクオート(')は検索する値としてはサポートされていません。クエリ文字列を分解してしまうからです。例えば、"comp.name = 'John's pizza' " という文字列はエラーを生成します。シングルクオートを含む値を検索したい場合には、プレースホルダーを使用を検討してください(以下参照)。
カッコを使用する
クエリ内でカッコを使用する事で、計算に優先順位をつけることができます。例えば、以下のようにクエリを整理することができます:
"(employee.age >= 30 OR employee.age <= 65) AND (employee.salary <= 10000 OR employee.status = 'Manager')"
queryString 引数内でのフォーミュラ挿入(上記参照)の代替として、formula オブジェクトをブール検索条件として直接渡すことができます。クエリにおいてフォーミュラオブジェクトを使用することは、トークナイズの利点を生かせる、コードが検索しやすく読みやすい、などといった面から推奨されています。
フォーミュラは、Formula あるいは Formula from string コマンドを使用して作成されている必要があります。この場合:
注: セキュリティ上の理由から、query() メンバーメソッド内でのフォーミュラの呼び出しは禁止することができます。querySettings 引数の詳細を参照してください。
フォーミュラに引数を渡す
query() メンバーメソッド内で呼び出されたformula 引数のどんなフォーミュラも、引数を受け取ることができます:
以下の短いコードは引数がどのようにメソッドに渡されるかという仕組みを示しています:
$settings:=New object("args";New object("exclude";"-")) // 引数を渡すargs オブジェクト
$es:=ds.Students.query("eval(checkName($1.exclude))";$settings) //args は$1 に受け取られる
さらなる使用例は、例題3にて提供されています。
4D Server: クライアント/サーバーにおいては、フォーミュラはサーバーで実行されます。このコンテキストにおいては、querySettings.args オブジェクトのみがフォーミュラに送信されます。
4D では、queryString 引数内のattributePath 、formula および value 引数に対してプレースホルダーを使用することができます。プレースホルダーとは、クエリ文字列に挿入する引数で、クエリ文字列が評価される時に他の値で置き換えられるものです。プレースホルダーの値はクエリの開始時に一度だけ評価されます。各要素に対して毎回評価されるわけではありません。
プレースホルダーには二つの種類があります。インデックスプレースホルダーおよび命名プレースホルダーです:
- | インデックスプレースホルダー | 命名プレースホルダー |
定義 | 引数はqueryString 引数内でに:paramIndex (例 :1, :2...) という形式で挿入され、それに対応する値は後に続くvalue 引数が提供します。最大で128個のvalue 引数を使用することができます | 引数は :paramName (例えば :myparam など) という形で挿入され、その値はquerySettings 引数のattributes または parameters オブジェクトで提供されます。 |
例題 | $r:=class.query(":1=:2";"city";"Chicago") | $o.attributes:=New object("att";"city") |
queryString 引数では全ての種類の引数を混ぜて使用することができます。queryString 引数では、attributePath 引数とformula 引数と value 引数に以下のものを含めることができます:
以下の理由から、クエリでのプレースホルダーの使用は推奨されます:
$vquery:="status = 'public' & name = "+myname //ユーザーが名前を入力する
$result:=$col.query("status='public' & name=:1";myname)
$result:=$col.query("address.city = :1 & name =:2";$city;$myVar+"@")
$result2:=$col.query("company.name = :1";"John's Pizzas")
null値の検索
null 値を検索する場合、プレースホルダーシンタックスは使用できません。なぜならクエリエンジンはnull を予期せぬ比較値としてみなすからです。例えば、以下のクエリを実行した場合:
$vSingles:=ds.Person.query("spouse = :1";Null) // これは動かない
$vSingles:=ds.Person.query("spouse = null") //正しいシンタックス
コレクション内のオブジェクトの属性内を、AND 演算子で結合された複数のクエリ引数を使用して検索する場合、異なる要素の中に条件値が含まれるエンティティではなく、全ての検索条件に合致するエンティティのみを取得したい場合があるかもしれません。このような検索をするためには、リンクされた引数を格納した単一の要素のみが見つかるように、クエリ引数をコレクションの要素に リンクする 必要があります。
例えば、以下の二つのエンティティを考えます:
エンティティ 1:
ds.People.name: "martin"
ds.People.places:
{ "locations" : [ {
"kind":"home",
"city":"paris"
} ] }
Entity 2:
ds.People.name: "smith"
ds.People.places:
{ "locations" : [ {
"kind":"home",
"city":"lyon"
} , {
"kind":"office",
"city":"paris"
} ] }
locationn のkind が"home"であり、そのcity が"paris" である人を探したい場合を考えます。以下のように書いた場合:
ds.People.query("places.locations[].kind= :1 and places.locations[].city= :2";"home";"paris")
... このクエリは"martin"と"smith" の両方を返します。何故なら"smith" も"kind" 属性が"home" である"location" を持っており、"city"が"paris"である"location" を持っているからです(ですがこれら2つは異なる要素です)。
同じコレクション要素内にある合致する引数があるエンティティのみを取得したい場合、引数をリンクする必要があります。クエリ引数をリンクするためには、以下のようにしてください:
上記の2つのエンティティにおいては、以下のように書いた場合:
ds.People.query("places.locations[a].kind= :1 and places.locations[a].city= :2";"home";"paris")
... クエリの結果は"martin" のみを返します。"kind"属性が"home"でありかつ"city"が"paris"であるエンティティはこれだけだからです。"smith"は"home" と"paris" が同じコレクション要素内にないため、クエリの結果には含まれません。
querySettings 引数には追加のオプションを格納したオブジェクトを渡す事ができます。以下のプロパティがサポートされます:
プロパティ | 型 | 詳細 | ||||||
parameters | オブジェクト | queryString 引数またはformula 引数で値の命名プレースホルダーを使用した場合に、このオブジェクトを渡します。値はプロパティ/値のペアで表現されており、プロパティは queryString またはformula に値の代わりに挿入したプレースホルダー名(":placeholder"など)で、値が実際に比較される値となります。インデックスプレースホルダー(value 引数に値を直接渡す方法)と命名プレースホルダーは、同じクエリの中で混ぜて使用することができます。 | ||||||
attributes | オブジェクト | queryString 引数またはformula 引数で属性パスの命名プレースホルダーを使用した場合に、このオブジェクトを渡します。属性パスはプロパティ/値のペアで表現されており、プロパティは queryString またはformula に属性パスの代わりに挿入したプレースホルダー名(":placeholder"など)で、値には属性パスを表す文字列または文字列のコレクションを指定することができます。値にはデータクラスのスカラー属性・リレート属性・オブジェクトフィールド内のプロパティへの属性パスを指定することができます。
| ||||||
args | オブジェクト | フォーミュラに渡す引数。args オブジェクトはフォーミュラ内部にて$1として受け取られるので、その値は$1.property という形で利用可能です(例題3参照)。 | ||||||
allowFormulas | ブール | クエリ内でフォーミュラの呼び出しを許可するにはTrue(デフォルト)。フォーミュラ実行を不許可にするためにはfalse を渡します。falseに設定されているときにquery() にフォーミュラが渡された場合、エラーが送られます(1278 - フォーミュラはこのメンバーメソッドでは許可されていません)。 | ||||||
context | テキスト | エンティティセレクションに適用された自動最適化コンテキストのラベル。このコンテキストはエンティティセレクションを扱うコードによって使用され、最適化の恩恵を受けることができます。この機能はクライアント/サーバー処理を想定して設計されています。詳細な情報については、クライアント/サーバーの最適化 の章を参照してください。 | ||||||
queryPlan | ブール | 返されるエンティティコレクションの中に、クエリの詳細を実行する直前に返す、あるいは返さないを指定します(クエリプラン)。返されたプロパティは各プロパティにクエリ・プランを、あるいは(複合クエリの場合)サブクエリを格納しているオブジェクトです。このオプションはアプリケーションの開発フェーズにおいて有用です。これは通常queryPath と組み合わせて使用されます。省略時のデフォルト: false. 注: このプロパティはentitySelection.query( ) および dataClass.query( ) メソッドにおいてのみサポートされます。 | ||||||
queryPath | ブール | 返されるエンティティコレクションの中に、実際に実行されたクエリの詳細を返す、あるいは返さないを指定します。返されたプロパティはクエリで実際に使用されたパス(通常はqueryPlan と同一ですが、エンジンがクエリを最適化した場合には異なる場合があります)と処理時間と見つかったレコード数を格納しているオブジェクトです。このオプションはアプリケーションの開発フェーズにおいて有用です。省略時のデフォルト: false. 注: このプロパティはentitySelection.query( ) および dataClass.query( ) メソッドにおいてのみサポートされます。 |
queryPlan と queryPath について
queryPlan/queryPath に格納されている情報には、クエリの種類(インデックス付きとシーケンシャル)とそれぞれに必要な寒クエリとその連結演算子が含まれます。クエリパスは見つかったエンティティの数と各検索条件を実行するににかかった時間も含まれます。この情報は、アプリケーションの開発中であれば解析することで有効に活用できます。一般的には、クエリプランとクエリパスの詳細は同一になるはずですが、4D はパフォーマンスの向上のために、クエリ実行時に動的な最適化を実装する事があるからです。例えば、4D エンジンは、そちらの方が早いと判断した場合には、インデックス付きクエリをシーケンシャルなものへと動的に変換する事があります。これは検索されているエンティティの数が少ないときに起き得ます。
例えば、以下のクエリを実行した場合を考えます:
$sel:=ds.Employee.query("salary < :1 and employer.name = :2 or employer.revenues > :3";50000;"Lima West Kilo";10000000;New object("queryPath";True;"queryPlan";True))
queryPlan:
{Or:[{And:[{item:[index : Employee.salary ] < 50000},{item:Join on Table : Company : Employee.employerID = Company.ID,subquery:[{item:[index : Company.name ] = Lima West Kilo}]}]},{item:Join on Table : Company : Employee.employerID = Company.ID,subquery:[{item:[index : Company.revenues ] > 10000000}]}]}
queryPath:
{steps:[{description:OR,time:63,recordsfounds:1388132,steps:[{description:AND,time:32,recordsfounds:131,steps:[{description:[index : Employee.salary ] < 50000,time:16,recordsfounds:728260},{description:Join on Table : Company : Employee.employerID = Company.ID,time:0,recordsfounds:131,steps:[{steps:[{description:[index : Company.name ] = Lima West Kilo,time:0,recordsfounds:1}]}]}]},{description:Join on Table : Company : Employee.employerID = Company.ID,time:31,recordsfounds:1388132,steps:[{steps:[{description:[index : Company.revenues ] > 10000000,time:0,recordsfounds:933}]}]}]}]}
この章では様々なクエリの例を紹介しています。
文字列をクエリ:
$entitySelection:=ds.Customer.query("firstName = 'S@'")
NOT 節を用いたクエリ:
$entitySelection:=ds.Employee.query("not(firstName=Kim)")
日付をクエリ:
$entitySelection:=ds.Employee.query("birthDate > :1";"1970-01-01")
$entitySelection:=ds.Employee.query("birthDate <= :1";Current date-10950)
値に対してインデックスプレースホルダーを使用したクエリ:
$entitySelection:=ds.Customer.query("(firstName = :1 or firstName = :2) and (lastName = :3 or lastName = :4)";"D@";"R@";"S@";"K@")
リレートされたデータクラスの値に対してインデックスプレースホルダーを使用したクエリ:
$entitySelection:=ds.Employee.query("lastName = :1 and manager.lastName = :2";"M@";"S@")
降順の宣言を含んだインデックスプレースホルダーを使用したクエリ:
$entitySelection:=ds.Student.query("nationality = :1 order by campus.name desc, lastname";"French")
値に対して命名プレースホルダーを使用したクエリ:
C_OBJECT($querySettings;$managedCustomers)
$querySettings:=New object
$querySettings.parameters:=New object("userId";1234;"extraInfo";New object("name";"Smith"))
$managedCustomers:=ds.Customer.query("salesperson.userId = :userId and name = :extraInfo.name";$querySettings)
値に対して命名プレースホルダーとインデックスプレースホルダーの両方を使用したクエリ:
C_OBJECT($querySettings;$managedCustomers)
$querySettings:=New object
$querySettings.parameters:=New object("userId";1234)
$managedCustomers:=ds.Customer.query("salesperson.userId = :userId and name=:1";"Smith";$querySettings)
queryPlan および queryPath オブジェクトがあるクエリ:
$entitySelection:=ds.Employee.query("(firstName = :1 or firstName = :2) and (lastName = :3 or lastName = :4)";"D@";"R@";"S@";"K@";New object("queryPlan";True;"queryPath";True))
//返されるエンティティセレクションには、以下の様なプロパティが返されます
C_OBJECT($queryPlan;$queryPath)
$queryPlan:=$entitySelection.queryPlan
$queryPath:=$entitySelection.queryPath
Collection 型の属性パスを用いたクエリ:
$entitySelection:=ds.Employee.query("extraInfo.hobbies[].name = :1";"horsebackriding")
Collection 型の属性パスとリンクされた属性を使用したクエリ:
$entitySelection:=ds.Employee.query("extraInfo.hobbies[a].name = :1 and extraInfo.hobbies[a].level=:2";"horsebackriding";2)
Collection 型の属性パスと複数のリンクされた属性を使用したクエリ:
$entitySelection:=ds.Employee.query("extraInfo.hobbies[a].name = :1 and extraInfo.hobbies[a].level = :2 and extraInfo.hobbies[b].name = :3 and extraInfo.hobbies[b].level = :4";"horsebackriding";2;"Tennis";5)
Object 型の属性パスを用いたクエリ:
$entitySelection:=ds.Employee.query("extra.eyeColor = :1";"blue")
IN 節を用いたクエリ:
$entitySelection:=ds.Employee.query("firstName in :1";New collection("Kim";"Dixie"))
NOT (IN) 節を用いたクエリ:
$entitySelection:=ds.Employee.query("not (firstName in :1)";New collection("John";"Jane"))
属性に対してインデックスプレースホルダーを使用したクエリ:
C_OBJECT($es)
$es:=ds.Employee.query(":1 = 1234 and :2 = 'Smith'";"salesperson.userId";"name")
//salesperson はリレートされたエンティティ
属性にインデックスプレースホルダーを、値に命名プレースホルダーを使用したクエリ:
C_OBJECT($es;$querySettings)
$querySettings:=New object
$querySettings.parameters:=New object("customerName";"Smith")
$es:=ds.Customer.query(":1 = 1234 and :2 = :customerName";"salesperson.userId";"name";$querySettings)
//salesperson はリレートされたエンティティ
属性と値に対してインデックスプレースホルダーを使用したクエリ:
C_OBJECT($es)
$es:=ds.Clients.query(":1 = 1234 and :2 = :3";"salesperson.userId";"name";"Smith")
//salesperson はリレートされたエンティティ
この章では属性に対して命名プレースホルダーを使用するクエリを紹介しています。
2つのエンティティをもつEmployee データクラスを考えます:
属性に対して命名プレースホルダーを使用したクエリ:
C_OBJECT($querySettings;$es)
$querySettings:=New object
$querySettings.attributes:=New object("attName";"name";"attWord";New collection("softwares";"Word 10.2"))
$es:=ds.Employee.query(":attName = 'Marie' and :attWord = 'Installed'";$querySettings)
//$es.length=1 (Employee Marie)
属性と値に対して命名プレースホルダーを使用したクエリ:
C_OBJECT($es;$queySettings)
C_TEXT($name)
$querySettings:=New object
//値に命名プレースホルダーを使用
//ユーザーは検索する名前の入力を求められる
$name:=Request("Please enter the name to search:")
If(OK=1)
$querySettings.parameters:=New object("givenName";$name)
//属性パスに命名プレースホルダーを使用
$querySettings.attributes:=New object("attName";"name")
$es:=ds.Employee.query(":attName= :givenName";$querySettings)
End if
以下は、クエリ内において引数ありまたは引数なしでフォーミュラを使用する様々な方法を紹介しているものです。
フォーミュラがqueryString 引数内のeval() でテキストとして渡されている方法:
C_OBJECT($es)
$es:=ds.Students.query("eval(length(This.lastname) >=30) and nationality='French'")
フォーミュラがプレースホルダーを通してフォーミュラオブジェクトとして渡されている方法:
C_OBJECT($es;$formula)
$formula:=Formula(Length(This.lastname)>=30)
$es:=ds.Students.query(":1 and nationality='French'";$formula)
フォーミュラオブジェクトのみが条件として渡されている方法:
C_OBJECT($es;$formula)
$formula:=Formula(Length(This.lastname)>=30)
$es:=ds.Students.query($formula)
複数のフォーミュラを適用することもできます:
C_OBJECT($formula1;$1;$formula2;$0)
$formula1:=$1
$formula2:=Formula(Length(This.firstname)>=30)
$0:=ds.Students.query(":1 and :2 and nationality='French'";$formula1;$formula2)
queryString 引数内のテキストフォーミュラが引数を受け取る方法:
C_OBJECT($es;$settings)
$settings:=New object()
$settings.args:=New object("filter";"-")
$es:=ds.Students.query("eval(checkName($1.filter)) and nationality=:1";"French";$settings)
//checkName メソッド内部:
C_TEXT($1;$exclude)
$exclude:=$1
$0:=(Position($exclude;This.lastname)=0)
同じcheckName メソッドを使用して、プレースホルダーとしてのフォーミュラオブジェクトが引数を受け取る方法:
C_OBJECT($es;$settings;$formula)
$formula:=Formula(checkName($1.filter))
$settings:=New object()
$settings.args:=New object("filter";"-")
$es:=ds.Students.query(":1 and nationality=:2";$formula;"French";$settings)
$settings.args.filter:="*" // change the parameters without updating the $formula object
$es:=ds.Students.query(":1 and nationality=:2";$formula;"French";$settings)
ユーザーがクエリを入力した場合などに、フォーミュラを禁止する方法:
C_OBJECT($es;$settings)
C_TEXT($queryString)
$queryString:=Request("Enter your query:")
if(OK=1)
$settings:=New object("allowFormulas";False)
$es:=ds.Students.query($queryString;$settings) // $queryString にフォーミュラが格納されていた場合にはエラーが生成されます。
End if
4D Blog - Add values to your generic orda queries
4D Blog - Placeholders for attribute paths in ORDA queries
collection.query( )
dataClass.all( )
dataClass.newSelection( )
DESCRIBE QUERY EXECUTION
entitySelection.query( )
entitySelection.queryPath
entitySelection.queryPlan
GET QUERY DESTINATION
QUERY
SET QUERY DESTINATION
プロダクト: 4D
テーマ: ORDA - データクラス
初出: 4D v17
変更: 4D v17 R5
変更: 4D v17 R6
ランゲージリファレンス ( 4D v19)
ランゲージリファレンス ( 4D v19.1)
ランゲージリファレンス ( 4D v19.4)
ランゲージリファレンス ( 4D v19.5)
ランゲージリファレンス ( 4D v19.6)
ランゲージリファレンス ( 4D v19.7)
ランゲージリファレンス ( 4D v19.8)