4D v15.4QUERY BY ATTRIBUTE |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
4D v15.4
QUERY BY ATTRIBUTE
|
QUERY BY ATTRIBUTE ( aTable {; conjOp}; objectField ; attributePath ; queryOp ; value {; *} ) | ||||||||
引数 | 型 | 説明 | ||||||
aTable | テーブル |
![]() |
セレクションまたはレコードを返すテーブル 省略時:デフォルトテーブル | |||||
conjOp | 演算子 |
![]() |
複数のクエリ(あれば)を連結する際に使用する結合演算子 | |||||
objectField | フィールド |
![]() |
属性をクエリするオブジェクトフィールド | |||||
attributePath | 文字 |
![]() |
属性の名前またはパス | |||||
queryOp | 演算子, 文字 |
![]() |
クエリ演算子(比較演算子) | |||||
value | テキスト, Number, 日付, 時間 |
![]() |
比較する値 | |||||
* | 演算子 |
![]() |
クエリ継続フラグ | |||||
QUERY BY ATTRIBUTE はobjectField、attributePath、queryOp そして value 引数を使用して定義されたクエリ文字列に合致するレコードを検索し、aTable に対しレコードのセレクションを返します。
注: オブジェクトフィールド(4D v15より新たに導入)についての詳細な情報に関しては、オブジェクトフィールドデータ型 のセクションを参照して下さい。
QUERY BY ATTRIBUTE はカレントプロセスにおいてaTable で指定されたテーブルのカレントセレクションを変更し、新しいセレクションの第一レコードをカレントレコードとします。aTable 引数が省略されていた場合、コマンドはデフォルトのテーブルへと適用されます。デフォルトテーブルが設定されていない場合、エラーが発生します。
任意のconjOp 引数を使用すると、QUERY BY ATTRIBUTE の呼び出しを複数のクエリ定義と組み合わせることができます。使用可能な接続演算子はQUERY コマンドに対して使用できるものと同じです:
接続子 | QUERY BY ATTRIBUTEで使用する記号 |
AND | & |
OR | | |
Except | # |
conjOp 引数は、複数のクエリの最初のQUERY BY ATTRIBUTE の呼び出しには使用しません。また単一のクエリの場合にも使用しません。複数のクエリにおいて省略された場合、AND (&) 演算子がデフォルトで使用されます。
objectField 引数には、クエリしたい属性のオブジェクトフィールドを渡します。そのオブジェクトフィールドがaTable 引数で指定したテーブルに自動または手動でリレートした1テーブルに属していた場合、objectField には他のテーブルに属するフィールドを指定することもできます。
attributePath 引数には値を比較したい属性の名前またはパスを渡します。単一の属性、例えば"age"などを渡す事もできます。この場合、この名前を持つすべての属性はレコード内にて比較されます。また、"children.girls.age"などのパスを渡す事もできます。この場合、それに合致する属性のみがレコード内にて比較されます。属性"x"が配列であった場合、QUERY BY ATTRIBUTE コマンドは、少なくとも一つの要素が条件に合致する属性"x"を含むレコードを検索します。配列内の属性を検索するためには、attributePath 引数内において属性”x”の名前に".[]"を付与することにより、QUERY BY ATTRIBUTE コマンドに対し、属性"x"が配列であるという事を指示する必要があります(例3を参照して下さい)。
注:
queryOp 引数は、objectField 引数と value 引数の間に適用される比較演算子です。以下の記号のどれか一つを渡す事ができます:
比較 | QUERY BY ATTRIBUTEで使用する記号 |
同値である | = |
同値でない | # |
未満 | < |
を超える | > |
以下 | <= |
以上 | >= |
注: 比較演算子を記号ではなく、テキスト表現で指定することも可能です。詳細な情報に関しては、QUERY コマンドの説明を参照して下さい。
value 引数は、attributePath 引数と比較するためのデータです。この値はattributePath引数と同じデータ型として評価されるものであればどんな表現も可能です。値は一度だけ、クエリの最初に評価されます。値はそれぞれのレコードに対して毎回評価されることはありません。文字列内に含まれる文字列をクエリする("を含む"クエリ)ためには、ワイルドカード記号(@)をvalue 引数に使用して検索したい文字列を隔離します(例:"@Smith@")。この場合、インデックスの利点を一部しか享受しないという点に注して下さい(データ保存のコンパクト化)。
属性によるクエリのストラクチャーは以下の様になります:
QUERY BY ATTRIBUTE([Table] ;[Table]ObjectField ;"attribute1.attribute2";=;value)
注: 全ての演算子(ただし"#"は除く)に対して、オブジェクトフィールドには属性が含まれている、というのが暗示的な前提条件になります。しかしながら、"#"演算子に対しては、未定義の属性も使用可能です(以下を参照して下さい)。
オブジェクトフィールドにおいては、"#"演算子を使用すると、フィールド内にて検索した値がどの属性にも存在しないレコードを検索します。このコンテキストにおいては、4Dは同じように以下の例を対応します:
例えば、以下のクエリは、Rexという名前ではない犬を飼っている人のレコードに加えて、犬を飼っていない人、あるいは名前のない犬を飼っている人のレコードも返します:
QUERY BY ATTRIBUTE([People];[People]Animals;"dog.name";#;"Rex")
その他の例:以下のクエリは、[Table]ObjectField 内で値がvalue ではないattribute2 属性を含むオブジェクトであるattribute1 属性を含んでいるオブジェクトを含んでいる全てのレコードに加え、attribute1 も attribute2 も含まないオブジェクトフィールドのレコードを返します:
QUERY BY ATTRIBUTE([Table] ;[Table]ObjectField ;"attribute1.attribute2";#;value)
この原則は配列属性にも適用されます。例えば、:
QUERY BY ATTRIBUTE([People];[People]OB_Field;"locations[].city";#;"paris")
上記のクエリは、Parisに住所を持っていないPeopleのレコードを返します。
属性が未定義であるレコードだけを特定して取得したい場合、空のオブジェクトを使用して下さい(例2を参照して下さい)。
属性によるクエリを複数組み合わせる際には、以下のルールが適用されます:
注: それぞれのテーブルは現在ビルトされたクエリを維持します。これはつまり、それぞれのテーブルに対して一つずつ、複数のクエリを同時に作成できるという事です。
どのように定義されたとしても、クエリには以下の制限がつきますNo matter which way a query has been defined:
日付はオブジェクト内において、データベース設定に沿った形で保存されています。デフォルトでは、タイムゾーンは考慮されます(SET DATABASE PARAMETER コマンドのJSON use local time を参照して下さい)。
!1973-05-22! -> "1973-05-21T23:00:00.000Z"
この設定はクエリにおいても影響するので、データベースを常に毎回同じ場所で使用し、データにアクセスる全てのマシンの設定が同じであれば何も心配する必要がありません。この場合、以下のクエリは、Birthday属性が!1973-05-22!("1973-05-21T23:00:00.00Z"として保存されている)に一致するレコードを正確に返します:
QUERY BY ATTRIBUTE([Persons];[Persons]OB_Info;"Birthday";=;!1973-05-22!)
GMT設定を使用したくない場合、これらの設定を以下の様にして変更する事ができます:
SET DATABASE PARAMETER(JSON use local time;0)
ただし、この設定のスコープはプロセスのみであるという点に注意して下さい。設定をこのように変更した場合、1965年10月1日は"1965-10-01T00:00:00.000Z"として保存されますが、クエリを実行する前に同じ引数を設定する必要が出てきます:
SET DATABASE PARAMETER(JSON use local time;0)
QUERY BY ATTRIBUTE([Persons];[Persons]OB_Info;"Birthday";=;!1976-11-27!)
この例においては、"age"属性は文字列か整数の値であり、年齢が20歳から29歳の人を検索したい場合を考えます。最初の2行は属性を整数としてクエリし(>=20 かつ < 30)、最後の1行はフィールドを文字列としてクエリします("2" で始まるが、"2"ではない値)。
QUERY BY ATTRIBUTE([Persons];[Persons]OB_Info;"age";>=;20;*)
QUERY BY ATTRIBUTE([Persons]; & ;[Persons]OB_Info;"age";<;30;*)
QUERY BY ATTRIBUTE([Persons];|;[Persons]OB_Info;"age";=;"2@";*)
QUERY BY ATTRIBUTE([Persons]; & ;[Persons]OB_Info;"age";#;"2") //実行したいので、ここでは最後の * は無い
QUERY BY ATTRIBUTE コマンドを使用すると、特定の属性が定義されている(あるいは定義されていない)レコードを探す事ができます。そのためには、空のオブジェクトを使用します。
//オブジェクトフィールド内にてEメールが定義されているレコードを探す
C_OBJECT($undefined)
QUERY BY ATTRIBUTE([Persons];[Persons]Info;"e-mail";#;$undefined)
//オブジェクトフィールド内にてZIPコード(郵便番号)が定義されていないレコードを探す
C_OBJECT($undefined)
QUERY BY ATTRIBUTE([Persons];[Persons]Info;"zip code";=;$undefined)
注: この特定のシンタックスは配列型属性ではサポートされていません。配列要素内でNULL値を検索した場合には不正な結果が返されます。
配列の属性を含むフィールドを検索したい場合を考えます。以下の二つのレコードがあった時、:
レコード1:
[People]name: "martin"
[People]OB_Field:
"locations" : [ {
"kind":"office",
"city":"paris"
} ]
レコード2:
[People]name: "smith"
[People]OB_Field:
"locations" : [ {
"kind":"home",
"city":"lyon"
} , {
"kind":"office",
"city":"paris"
} ]
... QUERY BY ATTRIBUTE コマンドに対して以下の宣言をすると、locationが"paris"である人を探します:
//配列の属性を".[]" シンタックスでフラグ付けする
QUERY BY ATTRIBUTE([People];[People]OB_Field;"locations.[].city";=;"paris")
//"martin" と "smith" を返す
注: 同じ配列の属性に対し複数の条件を定義した場合、合致した条件は必ずしも同じ配列の要素に対して適用されるとは限りません。以下の例においては、”kind"が"home"である”locations"要素と、"city"が"paris"である"locations"要素を持っているために"smith"が返されますが、これら二つは同じ要素ではありません:
QUERY BY ATTRIBUTE([People];[People]OB_Field;"locations.[].kind";=;"home";*)
QUERY BY ATTRIBUTE([People]; & ;[People]OB_Field;"locations.[].city";=;"paris")
//"smith"を返す