4D v17.4

dataClass.query( )

ホーム

 
4D v17.4
dataClass.query( )

dataClass.query( )  


 

説明  

dataClass.query( ) メソッドは、データクラスあるいはエンティティセレクション内にある全てのエンティティから、queryString 引数およびvalue 引数(任意)で指定された検索条件に合致するエンティティを検索し、データクラス内から見つかった全てのエンティティを格納するEntitySelection 型の新しいオブジェクトを返します。このメソッドにはレイジーローディングが適用されます。

合致するエンティティが見つからない場合、空のEntitySelection が返されます。

 queryString 引数は以下のシンタックスを使用します:

attributePath comparator value {logicalOperator attributePath comparator value}

詳細は以下の通りです:

  • attributePath: クエリを実行したいデータクラス属性の名前。例: "country"。この引数は有効であれば"country.name"などどんな属性パスも使用できます。
    属性パスがCollection 型である場合、全てのオカレンスを管理するためには[] 記法を使用してください。

    注: "." または "[ ]" といった特殊文字を含む名前の属性をクエリすることはできません。これらの文字列はクエリ文字列内で正しく評価されないからです。詳細な情報については、オブジェクトプロパティ識別子 の段落を参照してください。また、属性名には"="、 ">"、 "#"などといった、演算子として解釈されうる記号を含める事はできません(以下参照)。
  • comparator: attributePath 引数をvalue 引数を比較する記号。以下の記号がサポートされます:
    比較記号補足
    等しい=, ==一致するデータを取得。ワイルドカード(@)をサポートし、大文字小文字/アクセント記号の有無は区別しません。
    ===, IS一致するデータを取得。ワイルドカード(@)は標準文字として認識され、大文字小文字/アクセント記号の有無は区別しません。
    等しくない#, !=ワイルドカード(@)をサポート
    !==, IS NOTワイルドカード(@)は標準文字として認識
    未満<
    より大きい>
    以下<=
    以上>=
    含まれるINコレクション、あるいは複数の値の中の、どれか一つの値と等しいデータを取得します。
    宣言にNot 条件を適用するNOT複数の演算子が含まれる宣言の前にNOTを使用する場合にはカッコをつける必要があります。
    キーワードを含む%キーワードは文字列あるいはピクチャー型の属性中で使用されるものが対象です
  • value: コレクションあるいはエンティティセレクション内にある各オブジェクトのプロパティのカレント値に対して比較する値。プロパティと同じ型の式か、あるいはparamIndex 引数にプレースホルダーを渡す事もできます(以下参照)
    定数値はシングルクオートで括る事で渡します。定数としては次の二つは禁止されています:true, false "null" キーワードを使用する事で値をクエリ内で比較する事はできます。このクエリはnull および undefined プロパティを検索します。
    文字列の中の文字列を検索する("含んでいる"クエリ)ためには、value 引数でワイルドカード記号(@) を使用する事で検索する文字列を識別してください。例: "@Smith@"
    数値に対しては、浮動小数点はドットです。日付は次のフォーマットで書かれている必要があります:"YYYY-MM-DD"
    IN 記号を使用してのクエリの場合、value 引数の値は、コレクションか、属性パスの型に合致する、[]でくくられてカンマで区切られた値である必要があります(文字列においては、 "の記号は"\"でエスケープする必要があります)。
  • logicalOperator: 複数の条件をクエリ内で結合させるのに使用します(任意)。以下の論理演算子のいずれか一つを使用する事ができます(名前あるいは記号のどちらかを渡します):
    結合記号
    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')"

value 引数は、クエリがプレースホルダーを使用してビルドされているときには必ず使用しなければなりません。プレースホルダーとはクエリ文字列を挿入するタグで、クエリ文字が評価された時に他の値がそこに上書きされます。最大で128個のvalue 引数を使用する事ができます。

注: プレースホルダーの値は、任意のquerySettings 引数のparameters プロパティ内のコレクションとして渡す事もできます(ただしエンティティセレクションおよびデータクラスに対するクエリのみ)。詳細な情報については、以下のquerySettings 引数 の段落を参照してください。

queryString 引数には、各プレースホルダーに対してparamIndex を挿入します(これは"比較する値としてparamIndex 番目の引数を使用"ということを意味します)。そして必要な値をvalue 引数に渡します。例えば、Chicago に住んでいて給料が10,000 未満の従業員をクエリしたい場合、以下のように書く事ができます:

"employee.city = :1 & employee.salary < :2"; "Chicago";10000

値はクエリの初めに一度だけ評価されます。各要素に対して毎回は評価されません。

以下の二つの理由から、クエリでのプレースホルダーの使用は推奨されます:

  1. 悪意あるコードの挿入を防ぐ: ユーザーが入力した変数をクエリ文字列として直接使用した場合、ユーザーは余計なクエリ引数を入力する事でクエリ条件を変更する可能性があります。例えば、以下のようなクエリ文字列の場合を考えます:
     $vquery:="status = 'public' & name = "+myname //ユーザーが名前を入力する

    このクエリは非公開のデータはフィルタリングされているため、一見安全なように見えます。しかしながら、もしユーザーが例えばmyname エリアに"smith OR status='private' のようなものを入力した場合、クエリ文字列は解釈時に変更され、非公開なデータも返してしまう可能性があります。
    プレースホルダーを使用した場合、セキュリティ条件を上書きすることは不可能です:
     $result:=$col.query("status='public' & name=:1";myname)

    この場合、ユーザーがmyname エリアにsmith OR status='private' と入力した場合でも、それはクエリ文字列とはみなされず、値として渡されるだけです。"smith OR status='private' " という名前の人物を検索したところで、結果は失敗に終わるだけです。
  2. フォーマットや文字列の問題を心配する必要がありません。これに加えて、クエリ引数の中に変数や式を使用する事ができます。例:
     $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// これは動かない

これでは期待した結果を得る事はできません。null 値は引数の評価から4D によってエラーと判定されるからです(例えば、他のクエリから渡された属性、など)。このようなクエリのためには、直接クエリシンタックスを使用する必要があります:
 $vSingles:=ds.Person.query("spouse = null") //正しいシンタックス

注: この引数は、entitySelection.query( ) および dataClass.query( ) メソッドにおいてのみサポートされます。

querySettings 引数には追加のオプションを格納したオブジェクトを渡す事ができます。以下のプロパティがサポートされます:

プロパティ詳細
parametersコレクションqueryString 引数にプレースホルダーを使用する場合に比較する値(プレースホルダーに値を渡すもう一つの方法です)。他の値も直接value 引数に渡されていた場合、これらの値はプレースホルダーシークエンスの中に追加されます。
queryPlanブール返されるエンティティコレクションの中に、クエリの詳細を実行する直前に返す、あるいは返さないを指定します(クエリプラン)。返されたプロパティは各プロパティにクエリ・プランを、あるいは(複合クエリの場合)サブクエリを格納しているオブジェクトです。このオプションはアプリケーションの開発フェーズにおいて有用です。これは通常queryPath と組み合わせて使用されます。省略時のデフォルト: false
queryPathブール返されるエンティティコレクションの中に、実際に実行されたクエリの詳細を返す、あるいは返さないを指定します。返されたプロパティはクエリで実際に使用されたパス(通常はqueryPlan と同一ですが、エンジンがクエリを最適化した場合には異なる場合があります)と処理時間と見つかったレコード数を格納しているオブジェクトです。このオプションはアプリケーションの開発フェーズにおいて有用です。省略時のデフォルト: false

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:=dataClass.query("(firstName = :1 or firstName = :2) and (lastName = :3 or lastName = :4)";"D@";"R@";"S@";"K@")

プレースホルダーを使用していない標準クエリ:

 $entitySelection :=dataClass.query("firstName = 'S@'")

リレートされたデータクラスに対するクエリ:

 $entitySelection:=dataClass.query("lastName = :1 and manager.lastName = :2";"M@";"S@")

queryPlan と queryPath オブジェクトを返すクエリ:

 $entitySelection:=dataClass.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

プレースホルダーを使用して、値をコレクションとして渡したクエリ:

 $params:=New object
 $params.parameters:=New collection("D@";"R@";"S@";"K@")
 $entitySelection:=dataClass.query("(firstName = :1 or firstName = :2) and (lastName = :3 or lastName = :4)";$params)

NOT 宣言を使用したクエリ:

 $entitySelection:=dataClass.query("not(firstName=Kim)")

Collection 型の属性パスを使用したクエリ:

 $entitySelection:=dataClass.query("additionalInfo.hobbies[].name = horsebackriding")

Object 型の属性パスを使用したクエリ:

 $entitySelection:=ds.Employee.query("extra.eyeColor = :1";"blue")

IN 宣言を使用したクエリ:

 $entitySelection:=dataClass.query("firstName in :1";New collection("Kim";"Dixie"))

NOT (IN) 宣言を使用したクエリ:

 $entitySelection:=ds.Employee.query("not (firstName in :1)";New collection("John";"Jane"))

日付を使用したクエリ:

 $entitySelection:=dataClass.query("birthDate > :1";"1970-01-01")



参照 

collection.query( )
dataClass.all( )
dataClass.newSelection( )
entitySelection.query( )
entitySelection.queryPath
entitySelection.queryPlan

 
プロパティ 

プロダクト: 4D
テーマ: ORDA - データクラス

 
ページの目次 
 
履歴 

 
ARTICLE USAGE

ランゲージリファレンス ( 4D v17)
ランゲージリファレンス ( 4D v17.1)
ランゲージリファレンス ( 4D v17.2)
ランゲージリファレンス ( 4D v17.3)
ランゲージリファレンス ( 4D v17.4)