Page Contents
概要
検索 は、データまたは結果のセットを返すモデルの読取操作です。 次の表に示すように、フィルタ を使用して、Node APIとREST APIでLoopBackモデルを検索することができます。フィルタは、戻されるデータセットの基準を指定します。 2つのAPIの機能とオプションは同じですが、唯一の違いはHTTPリクエストとNode関数呼び出しで使用される構文です。 いずれの場合も、LoopBackモデルはJSONを返します。
検索 | モデル API (Node) | REST API |
---|---|---|
指定したフィルタを使用して、すべてのモデルインスタンスを検索します。 |
find(filter, callback)
ここで filter は検索フィルタを含むJSONオブジェクトです。
以下のフィルタを参照してください。
|
GET /modelName?filter...
モデル REST API - 一致するインスタンスの検索を参照してください。
以下のフィルタを参照してください。
|
指定したフィルタを使用して最初のモデルインスタンスを検索します。 |
findOne(filter, callback)
ここで filter は検索フィルタを含むJSONオブジェクトです。
以下のフィルタを参照してください。
|
GET /modelName/findOne?filter...
モデル REST API - 最初のインスタンスの検索を参照してください。
以下のフィルタを参照してください。
|
IDでインスタンスを検索します。 |
findById(id, [filter,] callback)
ここで省略可の filter は検索フィルタを含むJSONオブジェクトです。
以下のフィルタを参照してください。
|
GET /modelName/modelID
モデル REST API - IDによる検索を参照してください。
|
Important:
RESTによる検索は、URLクエリ文字列にリテラル文字列「filter」を含める必要があります。 Node API呼び出しには、JSONのリテラル文字列「filter」を含めません。
LoopBack APIエクスプローラは検索文字列に「filter」を追加しますが、 filter フィールドに文字列化したJSONを入力する必要があります。 また、あなたが使用している引用符が、丸くなっていたり活字風だったりの引用符(“ や ”)ではなく、適切なストレート引用符(”)であることを確認してください。これらは、しばしば視覚的に区別することが難しい場合があります。
Tip:
検索フィルタをcurlで試す場合、-g
または --globoff
オプションを使ってブラケット([
と]
)をリクエストURLの中で使えるようにしてください。
LoopBackは、次の種類のフィルタをサポートしています。
詳細は以下のフィルタ を参照してください。
例
フィルタに関する追加の例は、各種類のフィルタの記事を参照してください(例:Whereフィルタ)。
find()
メソッドで where と limit フィルタの両方を使用する例:
Account.find({where: {name: 'John'}, limit: 3}, function(err, accounts) { /* ... */ });
RESTを使った等価な例:
/accounts?filter[where][name]=John&filter[limit]=3
フィルタ
RESTとNode APIの両方で、任意の数のフィルタを使用して検索を定義できます。
LoopBackは、特定のフィルタ構文をサポートしています。SQLによく似ていますが、インジェクションなしで安全にシリアル化でき、JavaScriptネイティブであるように特別に設計されています。
以前は、この構文をサポートしていたのはPersistedModel.find()
メソッド(および関連するメソッド)のみでした。
The following table describes LoopBack’s filter types:
フィルタ種別 | 型 | 説明 |
---|---|---|
fields | Object・Array・String | 応答に含めたり除外したりするフィールドを指定します。 Fields フィルタを参照してください。 |
include | String・Object・Array | belongsToやhasManyなどの関係について、関連するモデルの結果を含めます。 Include フィルタを参照してください。 |
limit | Number | 返すインスタンスの数を制限します。 Limit フィルタを参照してください。 |
order | String | ソート順を指定指定します。(昇順・降順) Order フィルタを参照してください。 |
skip (オフセット) | Number | 指定した数のインスタンスを飛ばします。 Skip フィルタを参照してください。 |
where | Object | 検索条件を指定します。SQLのWHERE句に似ています。 Where フィルタを参照してください。 |
REST 構文
HTTP クエリ文字列にフィルタを指定するには以下のようにします。
?filter_filterType_=_spec_&_filterType_=_spec_....
1回のリクエストに適用できるフィルタの数は、URLの最大長によってのみ、制限されます。これは一般的に使用するクライアントに依存します。
Important:
クエリ文字列では、?filter
の直後に等号は書きません。例:
http://localhost:3000/api/books?filter[where][id]=1
Note: 詳細は https://github.com/hapijs/qs を参照してください。
Node 構文
find()
や findOne()
の最初の引数としてフィルタを指定するには以下のようにします。
{ filterType: spec, filterType: spec, ... }
適用できるフィルタの数に理論的な限界はありません。
ここで、
- filterType はフィルタの種類: where・include・order・ limit・skip・fieldsのいずれかです。
- spec はフィルタの仕様です。例えば where フィルタなら、 結果が一致しなければならない条件を書きます。 include フィルタなら、結果に含める関連フィールドを指定します。
REST 検索で「文字列化した」JSON を使う
上記の標準的なREST構文の代わりに、REST検索で「文字列化されたJSON」を使用することもできます。 これを行うには、次のようにNode構文用のJSONを使用します。
?filter={ Stringified-JSON }
Stringified-JSON はNode構文に沿った文字列化したJSONです。ただし、JSONではすべてのテキストキー/文字列を引用符(”)で囲む必要があります。
Important:
文字列化されたJSONを使用する場合、クエリ文字列の?filter
の直後に等号を使用する必要があります。
例: http://localhost:3000/api/books?filter={%22where%22:{%22id%22:2}}
例: GET /api/activities/findOne?filter={"where":{"id":1234}}
オブジェクトの配列をフィルタリングする
loopback-filters モジュールは、LoopBackのフィルタ構文を実装します。
このモジュールを使用すると、MyModel.find(filter)
でサポートされているのと同じフィルタ構文を使用して、オブジェクトの配列をフィルタリングできます。
Note:
すべてのモジュールがloopback-filter
を使用するように変換する予定です。このモジュールはLoopBackの一般的な「組み込み」フィルタリング機構になるでしょう。
ここでは、新しいモジュールを使用した基本的な例を示します。
var data = [{n: 1}, {n: 2}, {n: 3, id: 123}];
var filter = {where: {n: {gt: 1}}, skip: 1, fields: ['n']};
var filtered = require('loopback-filters')(data, filter);
console.log(filtered); // => [{n: 3}]
もう少し詳しく説明すると、コンマ区切り値(CSV)ファイルを解析して、価格列が10〜100のすべての値を出力する必要があるとします。 LoopBackフィルタ構文を使用するには、CSVコネクタか、メモリコネクタを使用する必要があります。両方とも、実際の目的には関係ない余分な作業が必要です。
CSVを(node-csv
のようなモジュールを使って)解析すると、次のようなオブジェクトの配列が得られます(ユニークなアイテムは10,000個あるとします)。
[
{price: 85, id: 79},
{price: 10, id: 380},
//...
]
これらの行をフィルタするには、以下のように一般的なJavaScriptを使うこともできます。
data.filter(function(item) {
return item.price < 100 && item.price >= 10
});
これはフィルタリングには非常に簡単ですが、ソート、フィールド選択、さらに高度な操作はややこしくなります。 さらに、通常は入力としてパラメータを受け入れます。
例えば以下のようなものです。
var userInput = {min: 10, max: 100}
data.filter(function(item) {
return item.price < userInput.min && item.price >= userInput.max
});
これを簡単にループバックフィルタとして書き直すことができます。
filter(data, {where: {input: {gt: userInput.min, lt: userInput.max}}})
または、フィルタオブジェクト構文をユーザー入力として採用するだけの場合は、次のようにします。
filter(data, userInput)
しかし loopback-filter、単に除外したり、含めたりするだけではありません。 フィールドの選択(フィールドを含む/除外する)・並べ替え・位置情報/距離の並べ替え・制限とスキップをサポートしています。 すべてがユーザー入力から簡単に作成できる宣言構文です。
LoopBackユーザーにとって、これは非常に強力なものです。
find()
フィルタ構文を使用して複雑なクエリを作成する典型的な方法を学びました。前提として、JavaScriptで(underscore.jsなどのライブラリを使用して)同じことを行う方法を理解する必要があります。一方、loopback-filters
モジュールを使えば、LoopBackサーバーと全く対話することなく、データベースをフィルタするためにサーバーに送信したのと正確に同じフィルタオブジェクトを、クライアントアプリケーションで再利用することができます。
入れ子になったプロパティのフィルタリング
Loopbackは、Mongodb、Cloudant、Memoryの3つのNoSQLコネクタで、入れ子になったプロパティをフィルタリングすることをサポートしています。
For example, model User
contains a nested property user.address.tags.tag
:
db.define('User', {
name: {type: String, index: true},
email: {type: String, index: true},
address: {
street: String,
city: String,
tags: [
{
tag: String,
}
]
}
});
users can do a nested query like User.find({where: {'address.tags.tag': 'business'}}
.
リレーショナル・データベースのコネクタは、入れ子になったプロパティのフィルタリングをサポートしていません。