IBM Cloud Docs
セレクター式の作成

セレクター式の作成

一般に、引数を取る演算子がある場合、その引数自体を、独自の引数を持つ別の演算子にすることができます。 この拡張により、より複雑なセレクター式が可能になります。

$regex などの組み合わせ論理演算子または配列論理演算子を使用すると、JSON タイプの索引を使用するときにデータベース全体がスキャンされ、パフォーマンスが低下する可能性があります。 等価演算子 ( $eq など) のみ $gt$gte$lt、および $lte (ただし $ne は除く) は、索引検索を有効にします。 索引が効率的に使用されるようにするには、照会ごとに Explain プランを分析します。

ほとんどのセレクター式は、演算子に対して期待どおりに動作します。 演算 $regex が使用するマッチング・アルゴリズムは*、*現在のところ PerlCompatible Regular Expression(PCRE)ライブラリに基づいています。 ただし、すべての PCRE ライブラリーが実装されるわけではありません。 さらに、 $regex 演算子の一部は、PCRE によって提供されるものを越えています。 実装されているものについての詳細は Erlang正規表現の情報を参照してください。

ソート構文

sort フィールドには、基本配列として表されるフィールド名と方向のペアのリストが含まれます。 最初のフィールド名と方向のペアは、ソートの最上位のレベルです。 さらにペアを指定する場合は、次のソート・レベルを指定します。

ソート・フィールドは任意のフィールドにすることができます。 必要な場合は、サブフィールドにドット表記を使用します。

方向の値は、昇順の場合は asc、降順の場合は desc です。

方向の値を指定しない場合は、デフォルトの asc が使用されます。

単純なソート構文の例を以下に示します。

[
	{
		"fieldName1": "desc"
	},
	{
		"fieldName2": "desc"
	}
]

両方のフィールドの方向がデフォルトの「昇順」である場合の単純なソート構文の例を以下に示します。

[
	"fieldNameA", "fieldNameB"
]

標準的な要件は、セレクターを使用してコンテンツを検索し、指定されたフィールドに従って結果を設定した方向でソートすることです。

ソートを使用するには、ソート・フィールドを含む索引を定義する必要があります。 json 索引を使用する場合は、ソートと同じ順序でフィールドを指定する必要があります。

現在、IBM Cloudant 照会では、ソート順序が異なる複数のフィールドはサポートされていません。そのため、方向はすべて昇順またはすべて降順のどちらかにする必要があります。

方向が昇順の場合は、オブジェクトの代わりにストリングを使用してソート・フィールドを指定できます。

ソート対象のフィールドのタイプを判別できない text 索引に対するソート照会のフィールド名については、フィールド・タイプの指定が必要になる場合があります。 以下に例を示します。

{
	"<fieldname>:string": "asc"
}
フィールド・タイプを指定すべき状況
照会で使用されるのはどの索引ですか? フィールド・タイプ要件
JSON 索引 なし
すべての文書のすべてのフィールドのテキスト索引 ソート・フィールドに 1 つのタイプがある文書がデータベースに含まれている場合は、照会でソート・フィールドを指定します。 ソート・フィールドに異なるタイプがある文書が含まれている場合も、照会でソート・フィールドを指定します。
他の任意のテキスト索引 照会のすべてのソート・フィールドのタイプを指定します。

次の構文を使用すると、すべての文書のすべてのフィールドのテキスト索引が作成されます。 "index": {}.

フィールドに異なるデータ・タイプが含まれている場合、ソート順は未定義です。 この特性は、テキスト索引とビュー索引の重要な相違点です。 データ・タイプが異なるフィールドのソート動作は、将来のバージョンで変更される可能性があります。

ソートを使用する単純な照会の例を以下に示します。

{
	"selector": {
		"Actor_name": "Robert De Niro"
	},
	"sort": [
		{
			"Actor_name": "asc"
		},
		{
			"Movie_runtime": "asc"
		}
	]
}

フィールドのフィルタリング

データベースからフィールドを選択するときに、文書に対して返されるフィールドを正確に指定できます。 2 つの利点を以下のリストに示します。

  • 結果は、アプリケーションに必要な文書の部分のみに制限されます。
  • 応答のサイズが縮小されます。

返されるフィールドは、配列として指定されます。

指定されたフィルター・フィールドのみが応答に含まれます。_idやその他のメタデータ・フィールドは自動的には組み込まれません。

一致する文書からフィールドを選択的に取得する例を以下に示します。

{
	"selector": {
		"Actor_name": "Robert De Niro"
	},
	"fields": [
		"Actor_name",
		"Movie_year",
		"_id",
		"_rev"
	]
}

ページネーション

IBM Cloudant 照会では、ブックマーク・フィールドによるページネーションをサポートしています。 すべての _find 応答には、ブックマークが含まれています。ブックマークは、後で照会が行われたときに再開する場所を決定するために IBM Cloudant が使用するトークンです。 照会結果の次のセットを取得するには、前の応答で受け取ったブックマークを次の要求に追加します。 セレクターは変更しないでください。そうしないと、予期しない結果になります。 後方にページ番号付けするには、前のブックマークを使用して前の結果セットを返すことができます。

ブックマークが存在しても、より多くの結果が保証されるわけではありません。 返された結果の数と要求されたページ・サイズを比較することにより、結果セットの終わりかどうかをテストできます。 返された結果が制限より小さい場合、それ以上の結果は結果セットに返されていません。

Explain プラン

IBM Cloudant 照会では、照会時に索引を指定しない限り、照会に応答するために使用する索引が選択されます。

使用する索引を指定すると、以下のようになります。 IBM Cloudant Query は、以下のロジックを使用します。

  • 照会プランナーはセレクター・セクションを参照し、照会で使用される演算子とフィールドに最も一致する索引を見つけます。 複数の JSON タイプ索引が一致する場合は、索引内のフィールド数が最も少ない索引が優先されます。 2 つ以上の候補索引がまだ存在する場合は、アルファベット順で最初の名前を持つ索引が選択されます。
  • json タイプの索引および text タイプの索引の両方がセレクターを満たす場合、デフォルトで json 索引が選択されます。
  • 以下の条件を満たす場合は、text タイプの索引が選択されます。
    • json タイプの索引と * タイプの索引の*両方がtext 同じフィールド (例えば fieldone など) に存在する。
    • text タイプの索引を使用しないとセレクターを満たすことができない。

例えば、text フィールドに json タイプの索引と foo タイプの索引があり、以下のサンプルのようなセレクターを使用するとします。

{
	"foo": {
		"$in": ["red","blue","green"]
	}
}

text タイプの索引はセレクターを満たすことができないため、IBM Cloudant 照会は json タイプの索引を使用します。

ただし、同じ索引を持つ別のセレクターを使用する場合もあります。

{
	"foo": {
		"$gt": 2
	}
}

この例では、次のようになっています。 IBM Cloudant 照会では、両方のタイプの索引がセレクターを満たすことができるため、 jsonタイプの索引が使用されます。

特定の照会で使用されている索引を識別するには、照会をデータとして、データベースの POST エンドポイントに _explain を送信します。 使用中の索引の詳細は、結果内の index オブジェクトに表示されます。

以下の例では、HTTP を使用して照会への応答に使用された索引を識別する方法を示しています。

POST /movies/_explain HTTP/1.1
Host: $SERVICE_URL
Content-Type: application/json
{
	"selector": {
		"$text": "Pacino",
		"year": 2010
	}
}

以下の例では、コマンド・ラインを使用して照会への応答に使用された索引を識別する方法を示しています。

curl "$SERVICE_URL/movies/_explain" \
	-X POST \
	-H "Content-Type: application/json" \
	-d '{
		"selector": {
			"$text": "Pacino",
			"year": 2010
		}
	}'
import com.ibm.cloud.cloudant.v1.Cloudant;
import com.ibm.cloud.cloudant.v1.model.ExplainResult;
import com.ibm.cloud.cloudant.v1.model.PostExplainOptions;

import java.util.HashMap;
import java.util.Map;

Cloudant service = Cloudant.newInstance();

Map<String, Object> selector = new HashMap<>();
selector.put("$text", "Pacino");
selector.put("year", 2010);

PostExplainOptions explainOptions =
    new PostExplainOptions.Builder()
        .db("movies")
        .selector(selector)
        .build();

ExplainResult response =
    service.postExplain(explainOptions).execute()
        .getResult();

System.out.println(response);
import { CloudantV1 } from '@ibm-cloud/cloudant';

const service = CloudantV1.newInstance({});

let selector: CloudantV1.Selector = {
    '$text': 'Pacino',
    'year': 2010
};

service.postExplain({
  db: 'movies',
  selector: selector
}).then(response => {
  console.log(response.result);
});
from ibmcloudant.cloudant_v1 import CloudantV1

service = CloudantV1.new_instance()

response = service.post_find(
  db='movies',
  selector={'$text': 'Pacino', 'year': 2010}
).get_result()

print(response)
postExplainOptions := service.NewPostExplainOptions(
    "movies",
    map[string]interface{}{
        "$text": "Pacino",
        "year":  2010,
    },
)

explainResult, _, err := service.PostExplain(postExplainOptions)
if err != nil {
  panic(err)
}

b, _ := json.MarshalIndent(explainResult, "", "  ")
fmt.Println(string(b))

前の Go の例では、以下のインポート・ブロックが必要です。

import (
   "encoding/json"
   "fmt"
   "github.com/IBM/cloudant-go-sdk/cloudantv1"
)

以下の例は、照会への応答に使用された索引を示す応答です。

{
	"dbname": "$ACCOUNT/movies",
	"index": {
		"ddoc": "_design/32372935e14bed00cc6db4fc9efca0f1537d34a8",
		"name": "32372935e14bed00cc6db4fc9efca0f1537d34a8",
		"type": "text",
		"def": {
			"default_analyzer": "keyword",
			"default_field": {},
			"selector": {},
			"fields": []
		}
	},
	"selector": {
		"$and": [
			{
				"$default": {
					"$text": "Pacino"
				}
			},
			{
				"year": {
					"$eq": 2010
				}
			}
		]
	},
	"opts": {
		"use_index": [],
		"bookmark": [],
		"limit": 10000000000,
		"skip": 0,
		"sort": {},
		"fields": "all_fields",
		"r": [
			49
		],
		"conflicts": false
	},
	"limit": 200,
	"skip": 0,
	"fields": "all_fields",
	"query": "(($default:Pacino) AND (year_3anumber:2010))",
	"sort": "relevance"
}

特定の索引を使用するように照会に指示するには、照会に use_index パラメーターを追加します。

use_index パラメーターの値は、以下のいずれかのフォーマットです。

  • "use_index": "$DDOC"
  • "use_index": ["$DDOC","$INDEX_NAME"]

特定の索引の使用方法については、以下の照会例を参照してください。

{
	"selector": {
		"$text": "Pacino",
		"year": 2010
	},
	"use_index": "_design/32372935e14bed00cc6db4fc9efca0f1537d34a8"
}