検索インデックス・フィルターの構文

DSE Searchノードでサポートされているインデックス付きのフィールドに対するクエリーのフィルターの構文について説明します。

DataStax Enterprise Searchノードは、インデックス付きフィールドに対するCQLクエリーのフィルタリングをサポートしています。DSEデータベースに接続するアプリケーションは、全文検索を使用してCQLクエリー内でこれらのフィールドに対するフィルタリングを実行できます。
注: アプリケーションでは、検索インデックス・カラムでクエリーをフィルタリングするために、Apache Solr APIsを使用する必要はなくなりました。

構文

CQL SELECT文で、以下の構文を使用して結果をフィルター処理します。

SELECT selectors
  FROM table
  WHERE (indexed_column_expression | solr_query = 'search_expression') 
  [ LIMIT n ]
  [ ORDER BY column_name ] ;
以下のように検索インデックス・カラムにフィルターを書き込みます。

制限事項とベスト・プラクティス

検索インデックス付きのフィールドでのCQLクエリーのフィルタリングには、以下の制限事項が適用されます。
  • 検索インデックス・クエリーはデフォルトで同等のLIMIT 10に設定されます。
  • ページネーションはデフォルトでオフになっています。
    注: dse.yamlのcql_solr_query_pagingオプションは、どのような場合にページネーション(カーソルとも呼ばれる)を使用するかを指定します
  • Solrの制限事項ページネーションに適用されます。
  • クエリーの結果セットが小さいほど、ページングをオフにした状態のパフォーマンスが向上します。
  • 制限事項と既知のApache Solrの問題はDSE Searchクエリーに適用されます。たとえば、トークン化された文字列フィールドのソート結果が正しくないなどの問題です。
  • カラム別名は、検索インデックス・クエリーでサポートされていません。
  • DSE SearchAnalyticsクラスターでクエリーされるすべてのフィールドは、検索インデックス・スキーマ定義で定義される必要があります。検索インデックス・スキーマ・カラムで定義されていないフィールドは、Sparkクエリーから返される結果から除外されます。

インデックス付きカラム名

DSE Searchノードでは、検索インデックス・カラムを使用してクエリーをフィルター処理します。

DataStax Enterprise Searchノードでは、インデックス付きカラムでクエリーがフィルター処理されるとき、対応するSolrドキュメントが使用されます。パーティション・キーが完全に定義されていないクエリーでインデックス付きカラムをフィルター処理する場合、ALLOW FILTERINGは必要ありません。

検索インデックスは現在、フィルター処理について、LIKEIS NOT NULLなどのCQL演算子、範囲、および=/!=をサポートしています。「ネイティブCQL検索クエリー」を参照してください。

フィルターを組み合わせてより複雑なクエリーを作成します。
SELECT * FROM test.test WHERE 
title IS NOT NULL AND 
collection CONTAINS 'Anaisa Pye' 
AND age > 35;

ORDER BYを使用してソートします。

solr_query q形式の使用

検索インデックスとプレーン・テキストのSolr qパラメーター構文を使用してクエリーをフィルター処理します。

プレーン・テキストのSolr qパラメーター構文を使用して、solr_queryオプションを使用するクエリーをフィルター処理します。 例については、「単語によるフィルター処理」を参照してください。
solr_query = 'q_expression'

単一カラムでのフィルター処理

name列にcatdogが含まれており、 fishが含まれていないpetsテーブルの行を検索するには、以下のように入力します。
SELECT * FROM pets WHERE solr_query='name: cat name: dog -name:fish';
注: Solr q式で一重引用符などのパンクチュエーションを使用するには、「solr_queryの文字のエスケープ」を参照してください。

結果の制限

特定のカラムを指定すると、DSE Searchは、指定されたカラムだけを取得し、それらのカラムを結果行の一部として返します。DSE Searchは、select式として射影(SELECT a, b, c…)のみをサポートし、関数はサポートしていません。以下の例ではnameカラムのみを取得します。
SELECT name FROM keyspace.table WHERE solr_query='name:cat name:dog -name:fish'
LIMIT句を使用して、返す行の数を指定します。以下の例では1行のみを取得します。
SELECT * FROM keyspace.table WHERE solr_query='name:cat name:dog -name:fish' LIMIT 1

count関数の使用

CQL SolrクエリーでCount()関数を使用すると、Solrクエリーを満たす行数が返されます。
SELECT count(*) FROM table WHERE solr_query = '...';

count()をLIMITまたはファセットと組み合わせて使用すると、エラーが発生します。

ドライバーのすべての応答クエリーにカスタム・ペイロードがあり、検出されたドキュメントの総数が返されます。この値は、DSESearch.numFoundとして入力されます。

solr_query JSON形式の使用

JSON形式の式を使用して、高度なフィルターをCQLクエリーに適用します。

cassandra.yaml

cassandra.yamlファイルの場所は、インストールのタイプによって異なります。
パッケージ・インストール /etc/dse/cassandra/cassandra.yaml
tarボール・インストール installation_location/resources/cassandra/conf/cassandra.yaml

dse.yaml

dse.yamlファイルの場所は、インストールのタイプによって異なります。
パッケージ・インストール /etc/dse/dse.yaml
tarボール・インストール installation_location/resources/dse/conf/dse.yaml

DSE Searchは、JSON形式の式を使用してCQLクエリーにフィルターを適用する高度なSolr検索機能をサポートしています。「検索クエリーのデフォルトのTimeZone(UTC)のオーバーライド」も参照してください。

JSONクエリー構文

JSONクエリー式の構文は、JSON文字列です。JSONベースのクエリー式は、以下のパラメーターに加えてローカル・パラメーターをサポートしています。
{
  "q": query_expression (string), 
  "fq": filter_query_expression(s) (string_or_array_of_strings, ...),  
  "facet": facet_query_expression (object) 
  "sort": sort_expression (string), 
  "start": start_index(number),
 timeAllowed: search_time_limit_ms,  
  "TZ": zoneID),   //  Any valid zone ID in java TimeZone class                            
  "paging": "driver" (string),
  "distrib.singlePass": true|false (boolean),
  "shards.failover": true|false (boolean),    // Default: true
  "shards.tolerant": true|false (boolean),    // Default: false
  "commit": true|false (boolean),
  "route.partition": partition_routing_expression (array_of_strings), 
  "route.range": range_routing_expression (array_of_strings), 
  "query.name": query_name (string),
}
例を次に示します。
SELECT id FROM nhanes_ks.nhanes WHERE solr_query='{"q":"ethnicity:Asian"}';
SELECT id FROM nhanes_ks.nhanes WHERE solr_query='{"q":"ethnicity:Mexi*", "sort":"id asc"}' LIMIT 3;
SELECT * FROM mykeyspace.mytable WHERE solr_query='{"q":"{!edismax}quotes:yearning or kills"}';
注: Apache Solr Extended DisMaxクエリー・パーサー(eDisMax)をsolr_queryとともに使用するには、defaultSearchFieldをスキーマに含める必要があります。

分散クエリーをシャード障害耐性にする

分散クエリーは多くのシャードにアクセスするため、クエリーのシャード障害耐性を向上させることで、クエリー実行の成功率が高まります。shards.failoverパラメーターとshards.tolerantパラメーターを使用して、JSONクエリー中に発生するクエリーのフェイルオーバーとシャード障害耐性を定義します。
有効な構成 説明
"shards.failover": true,
"shards.tolerant": false,
このデフォルトの構成を使用すると、クエリー・フェイルオーバーが有効になり、フォールト・トレランスが無効になります。エラーから復旧の見込みが妥当と判断される場合は、失敗したシャード要求をリトライしてください。
"shards.failover": false,
"shards.tolerant": true,
クエリー・フェイルオーバーが無効になります。フォールト・トレランスが有効になります。クエリーが部分的にしか正常に完了せず、すべてのノードに対して正常に完了しなかった場合でも、クエリーを正常な完了とします。
"shards.failover": false,
"shards.tolerant": false,
クエリー・フェイルオーバーが無効になります。フォールト・トレランスも無効になります。
フェイルオーバーと部分的な結果のトレランスは同じJSONクエリーに共存できません。クエリーは、単一のパラメーターのみに対するトレランスの有効化をサポートしています。
注: ディープ・ページングがオンの場合、shards.tolerantパラメータはサポートされません。

その他のフォールト・トレランスの構成オプションには、netty_client_request_timeoutdse.yaml )と、read_request_timeout_in_mscassandra.yaml)があります。

Apache Solr/Apache Lucene®特殊文字であるリテラル文字を使用したJSONクエリー

SolrとLuceneは、クエリー構文に使用されている特殊文字のエスケープをサポートしています。
1. Solr/Luceneのエスケープされた特殊文字
文字 説明
+ プラス。必要な検索用語の演算子。
- マイナス。除外する検索用語の演算子。
&& 二重アンパサンド。AND演算子。いずれかの演算子の両方の用語が一致する必要があります。
|| 二重パイプ。OR演算子。
! エクスクラメーション・マーク。NOT演算子。
( 左かっこ
) 右かっこ
" 二重引用符
~ チルダ
* アスタリスク
? クエスチョンマーク
に含まれています: コロン

solr_queryとともにJSONを使用する場合は、Lucene特殊文字であるリテラル文字の追加の構文が必要です。

単純な検索文字列の構文:
単純な検索文字列 mytestuser1?
Solrクエリー name:mytestuser1\?
CQL Solrクエリー solr_query='{"q":"name:mytestuser1\\?"}'
複雑な検索文字列の構文:
複雑な検索文字列 (1+1):2
Solrクエリー e:\(1\+1\)\:2
CQL Solrクエリー solr_query='{"q":"e:\\(1\\+1\\)\\:2"}'

JSONクエリーによるフィールド、クエリー、および範囲のファセット化

ファセットJSONオブジェクト内のファセット・パラメーターを指定して、Solrクエリー内のフィールド、クエリー、および範囲のファセット化を実行します。分散されたピボットのファセット化がサポートされています。ファセットを指定するためのクエリー構文を簡潔にするには、以下を行います。
  • HTTP APIで要求されるファセット・プレフィックスを使用せずに各ファセット・パラメーターを指定する。
  • 複数のファセット・フィールドとクエリーをJSON配列内で表現する。
ファセット化された検索の例
SELECT * FROM solr WHERE solr_query='{"q":"id:*","facet":{"field":"type"}}';
クエリー・ファセットの例
SELECT * FROM solr WHERE solr_query='{"q":"id:*","facet":{"query":"type:0"}}';
複数のクエリーの例
SELECT * FROM solr WHERE solr_query='{"q":"id:*","facet":{"query":["type:0","type:1"]}}';
分散されたピボットのファセット化の例
SELECT id FROM table WHERE solr_query='{"q":"id:*","facet":{"pivot":"type,value","limit":"-1"}}'
範囲ファセットの例
SELECT * FROM solr WHERE solr_query='{"q":"id:*","facet":{"range":"type", "f.type.range.start":-10, "f.type.range.end":10, "range.gap":1}}}';
返される結果は、各カラムがファセットの出力(フィールド、クエリー、または範囲)に対応した単一行の形式で出力されます。ファセット結果は複雑でネストされている場合があるため、値はJSON BLOBとして表されます。例を次に示します。
facet_fields           | facet_queries
------------------------+-------------------------
 {"type":{"0":2,"1":1}} | {"type:0":2,"type:1":1}
日付別範囲ファセットの例
SELECT * FROM solr WHERE solr_query='{"q":"business_date:*","facet":{"range":"business_date", "f.business_date.range.start":"2015-01-01T00:00:00Z", "f.business_date.range.end":"2015-08-01T00:00:00Z", "f.business_date.range.gap":"+1MONTH"}}';
警告: Solrの範囲ファセットの先頭、末尾、および中間で、マルチノード・クラスターについて不正確で整合性の低い結果が返される場合があります。SOLR-6187およびSOLR-6375を参照してください。
間隔ファセットの例
SELECT * FROM solr WHERE solr_query='{"q":"id:*","facet":{"interval":"id", "interval.set":"[*,500]"}';

分散クエリーのトレース

分散クエリーの実行時、トークン範囲セットの処理は各ノードが行います。シャードは、ノードと範囲の組み合わせです。シャード・トークン範囲は以下の場所で報告されます。
  • HTTPクエリーのshards.info応答内。
  • cassandra.trace=trueを指定するHTTPクエリーと、ドライバー・レベルのトレースを有効にするCQL Solrクエリーのsystem_traces.eventsテーブル内。

JSON単一パス分散クエリー

CQL Solrクエリーでは単一パス分散クエリーがサポートされています。単一パス分散クエリーは高度な機能であるため、クエリーが実行された行の取得中に1回のネットワーク往復の転送が保存されます。

標準の2パス・クエリーの代わりに単一パス分散クエリーを使用するには、JSONクエリー式でdistrib.singlePassブーリアン・パラメーターを指定します。
SELECT * FROM ks.cf WHERE solr_query = '{"q" : "*:*", "distrib.singlePass" : true}' 
単一パス分散クエリーを使用すると、ディスクとネットワークのオーバーヘットが増える可能性があるため、運用コストがかかります。単一パス・クエリーでは、各ノードはクエリーを満たす行をすべて読み取り、コーディネーター・ノードに返します。通常の分散クエリーではネットワークを2回往復します。1回目はクエリーを満たすIDをDSE Searchから取得し、2回目は最初のステップで取得したIDに基づいて、クエリーを満たす行のみをデータベースから取得します。単一パス分散クエリーは、検出されたドキュメントのほとんどが検索結果に表示される場合に最も効果的です。これらのドキュメントのほとんどがコーディネーター・ノードに返されない場合は効果はありません。たとえば、コーディネーター・ノードから単一ノードに分けるだけの分散クエリーは、単一パス・クエリーとしては最も効果的です。

CQLの単一パス分散クエリーは、追加のdistrib.singlePassブーリアン・パラメーターがJSONクエリーに含まれている場合にサポートされています。

単一パス・クエリーでは、検索スキーマで定義されているドキュメント・フィールドのみがクエリー結果として返されるという制約があります。この制約は、動的フィールド・マッピングに従っていないマップ・エントリーにも適用されます。

JSONクエリーのnameオプション

以下の構文を使用して、パフォーマンス・オブジェクトのメトリクスと監視をサポートするようにクエリーに名前を付けます。クエリーに名前を付けると、タグ付けやJMX操作などに役立ちます。
SELECT id FROM nhanes_ks.nhanes WHERE solr_query=' {"query.name":"Asian subjects", "q":"ethnicity:Asia*"}' LIMIT 50;

JSONクエリーのcommitオプション

ドキュメントを一括で読み込んだ後にカスタム・クエリーを実行し、自動ソフト・コミットが無効になっている(または、頻度が極端に低い値に構成されている)場合、JSONクエリーのcommitオプションを使用して、すへての保留中の更新がソフト・コミットされていることを確認してからクエリーを実行します。コミットによって、クエリーが最新のデータを取得できます。

警告: プロダクション・クラスターに対する稼働中の操作にJSONのcommitオプションを使用しないでください。commitオプションは、通常の自動ソフト・コミット・プロセスまたはCOMMIT SEARCH INDEXに置き換わるものではありません。
デフォルトでは、commitオプションはfalseに設定されています。以下の例では、commitオプションをtrueに設定します。
SELECT * FROM wiki.solr 
WHERE solr_query='{"q":"title:Asia*", "commit":true}' 
LIMIT 50;

ドライバーを使用してページングを動的に有効にするクエリー

cql_solr_query_pagingdse.yamloffに設定されているときにページングを動的に有効にするには、Solrページング・パラメータをドライバー("paging":"driver")に設定します。例:
SELECT id FROM wiki.solr 
WHERE solr_query= '{"q":"*", "sort":"id asc", "paging":"driver"}' ;

クエリーの時間制限

DSE Searchは、Solr timeAllowedパラメーターを使用してクエリーの時間制限をサポートしています。
制約事項: DSE Searchは、ネイティブSolrとは異なります。
  • timeAllowedを超過すると例外がスローされます。
  • timeAllowedを超過し、追加のshards.tolerantパラメーターがtrueに設定されている場合、アプリケーションはそれまでに収集した部分的な結果を返します。

部分的な結果が返されると、CQLカスタム・ペイロードには、DSESearch.isPartialResultsキーが含まれます。

30秒のタイムアウトの例:
SELECT * FROM users 
WHERE solr_query = '{ "q": "*:*", "timeAllowed":30000}';

solr_queryの文字のエスケープ

基本または高度なsolr_query式の特殊文字をエスケープする方法。

Solrクエリーでは、クエリー構文に含まれている特殊文字をエスケープする必要があります。

2. Solr/Luceneのエスケープされた特殊文字
文字 説明
+ プラス。必要な検索用語の演算子。
- マイナス。除外する検索用語の演算子。
&& 二重アンパサンド。AND演算子。いずれかの演算子の両方の用語が一致する必要があります。
|| 二重パイプ。OR演算子。
! エクスクラメーション・マーク。NOT演算子。
( 左かっこ
) 右かっこ
" 二重引用符
~ チルダ
* アスタリスク
? クエスチョンマーク
に含まれています: コロン

これらの文字をエスケープするには、エスケープする文字の前にスラッシュ(\)を含めます。たとえば、リテラル二重引用符(")文字を検索するには、\"としてSolrの"をエスケープします。

solr_queryを使用する場合、CQL SolrまたはJSON形式を使用して特殊文字をエスケープできます。
CQL Solr
...WHERE solr_query='field:value'
JSON
WHERE solr_query='{ "q": "field:value"}'

また、JSONエンコード・クエリーでは、その値が特殊文字をJSON形式でエスケープしたものである必要があります。

二重引用符を含むクエリーでは、3つのスラッシュ\\\を使用します。
  • クエリー構文の場合:"をエスケープするには1つのスラッシュ\を使用します。
  • JSON文字列構文の場合:\をエスケープするには2つのスラッシュ\\を使用します。

    \"の両方の文字をエスケープするには3つのスラッシュ\\\を使用して、\\(エスケープ文字のエスケープ)と\"(二重引用符のエスケープ)を生成します。

単一引用符のエスケープ

  • 単一引用符(')を二重にする
    CQL
    ...WHERE solr_query='name:Walter''s'
    JSON
    ...WHERE solr_query='{ "q": "Walter''s"}'
  • 文字列定数にはドル記号引用符を使用する
    CQL
    ...WHERE solr_query=$$name:Walter's$$
    JSON
    ...WHERE solr_query=$${ "q": "Walter's"}$$

二重引用符のエスケープ

CQL
Solrのエスケープの場合は単一引用符(')を二重にしてバックスラッシュ(\)を追加する
...WHERE solr_query='name:Walter\''s'
JSON
JSONの場合は\"の両方の文字をエスケープするために\\\"にする
...WHERE solr_query='{ "q": "Walter\\\"s"}'

完全一致クエリーとあいまい一致クエリーの例

完全一致の句クエリー
以下のように、二重引用符を含んでいる電子メール・アドレス(greenr"q@example.com)を含む行の場合:
INSERT INTO users(id, email) VALUES(1, 'greenr"q@example.com')"
二重引用符で囲まれている電子メール・アドレスを検索するには、句クエリーを実行します。
SELECT * FROM users where solr_query = '
{ "q": "*:*", "fq": "email:\"greenr\\\"q@example.com\""}
';
あいまい一致クエリー
以下のように、二重引用符を含んでいる同じ電子メール・アドレス(greenr"q@example.com)を含む行の場合:
select * from test.users where solr_query='{"q":"email:r\\\"q@example"}' ;
 id    | email                 | solr_query
------+-------+------------------------------
 1     | greenr"q@example.com  | null
(1 rows)
r"q@exampleを含むすべての電子メール・アドレスを検出する単語クエリー(あいまい検索)では、二重引用符を削除しますが、電子メール・アドレスに含まれている二重引用符をエスケープするための三重の引用符は保持します。
SELECT * FROM users where solr_query = '
{ "q": "*:*", "fq": "email:r\\\"q@example"}
';

solr_queryとともにJSONを使用する場合は、Lucene特殊文字であるリテラル文字の追加の構文が必要です。Solr特殊文字であるリテラル文字を使用したJSONクエリー」を参照してください。