2.14. スマートクエリ¶
スマートクエリは、自然言語を使ってクエリを記述する機能です。まず使用例を示します。
サンプル1
>>> s = 'name starts with "S"'
>>> print db.smart_query(db.person, s).select()
person.id,person.name
2,Socosapo
3,Saduduco
personテーブルのnameフィールドで、先頭文字が ‘S’ のものを取得します。
DAL クラスのメソッドとして smart_query()
が定義されており、呼び出すと Set インスタンスを返します。
つまりこのメソッドは、渡したパラメータを、Setインスタンスに変換します。
smart_query メソッドは2つのパラメータを取ります。一つはクエリの対象となるフィールドもしくはテーブルのリスト・タプル型の値(fields)、 もう一つはスマートクエリのクエリ文字列(text)です。これらを詳細に説明します。
- fields
- このパタメータはクエリ式で使用するフィールドを指定します。もしテーブルを指定した場合、テーブルの全フィールドを使用可能になります。 フィールドもしくはテーブルが複数ある場合、リストもしくはタプル型の値で指定します。
- text
フィールド名と共に演算子を使った、クエリ文字列をパラメータで渡します。演算子として次のキーワードが使用可能です。
演算子 キーワード 論理積(and) and & 論理和(or) or | 否定(not) not ~ 等価 [1] equal [2] equal to [2] is [2] == = 非等価 not equal to [2] not equal [2] equals [2] <> != 小なり less than [2] < 大なり greater than > 小なりイコール less or equal than [2] equal or less than [2] less or equal [2] equal or less [2] <= =< 大なりイコール greater or equal than [2] equal or greater than [2] greater or equal [2] equal or greater [2] => >= 前方一致検索 starts with [2] startswith 後方一致検索 ends with [2] endswith 部分一致検索 contains あいまい検索 like
[1] (1, 2) textもしくはstringタイプのフィールドに等価を使い、値に定数を使っていない場合、演算子は等価ではなく「あいまい」検索(like)に変換されます。
[2] (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18) このキーワードでは is を先頭に付けることができます。 フィールド名ではなく、Fieldインスタンスを文字列に変換した形式(例 person.name など)も使用可能です。
注意点
- クエリ文字列に記述したものは、全て内部で小文字に変換されます。このような動作に問題がある場合、定数を使用します。
- 定数の指定は、シングルクォーテーション(’)もしくはダブルクォーテーション(”)で値を囲みます。
- Version 1.99.7以前はバグのため、text及びstring型以外の値を等価で記述するには、定数で指定する必要があります(サンプル5を参照)。
- クエリ文字列で join は表現できないようです。
2.14.1. 使用例¶
幾つかスマートクエリを使ったサンプルを示します。
サンプル2
>>> s = 'name starts with "S"'
>>> print db.smart_query(db.person.name, s).select()
person.id,person.name
2,Socosapo
3,Saduduco
fieldsの指定でTableインスタンスではなく、Fieldインスタンスを指定しています。 Fieldインスタンスを指定した場合は、指定していないフィールドはクエリ文字列で使用することはできません。
サンプル3
>>> s = 'name is s%'
>>> print db.smart_query(db.person, search).select()
person.id,person.name
2,Socosapo
3,Saduduco
[1] でも説明していますが、textもしくはstringタイプのフィールドに 等価 を使用し、値に 定数 を使っていないと、 内部であいまい検索(like)に変換されます。なおSQLiteを使用する場合、likeでは大文字と小文字を区別しません。
定数を使用する場合は、like演算子を使用します。
>>> s = 'person.name like "s%"' >>> print db.smart_query(db.person, s).select() person.id,person.name 2,Socosapo 3,Saduduco
サンプル4
>>> s = 'name is ends with co'
>>> print db.smart_query(db.person, s).select()
person.id,person.name
3,Saduduco
一部の演算子キーワードの前に、 is キーワードを付けることもできます( [2] のキーワード)。
サンプル5
>>> s = 'person.id is "2" or person.name is d%'
>>> print db.smart_query(db.person, s).select()
person.id,person.name
1,Damapoda
2,Socosapo
person.id==2 と person.name is d% の論理和で検索します。ここでidを定数で指定しています。これは次のようにも表現できます。
s = 'person.id is 2 or person.name is d%'Version 1.99.7 より新しいweb2pyで、使用可能です。
サンプル6
>>> s = 'person.name is s% and dog.name is s%'
>>> print db.smart_query([db.person,db.dog], s).select(join=db.dog.on(db.person.id==db.dog.owner))
person.id,person.name,dog.id,dog.owner,dog.name
2,Socosapo,2,2,Soducomo
スマートクエリでは テーブル結合(join) は表現できません。このため select()
メソッドで join を設定する必要があります。
クエリ文字列に複数のテーブルのフィールドを指定する場合、fieldパラメータに必要なテーブルをリスト型もしくはタプル型で指定してください。
参考: smart_query (experimental) | smart_query (実験的)
スマートクエリの用途として、サービスへの適用も考えられます。
参考: smart_query (experimental) service | smart_query (実験的試み)