**分析コンポーネント**
分析コンポーネントを使用すると、結果セットに対して複雑な統計的集計を計算できます。
分析コンポーネントは非推奨です。JSON ファセット APIにある同様の機能を検討することをお勧めします。JSON ファセットでは現在対応できない必要な機能がある場合は、プロジェクトに通知してください。 |
このコンポーネントは、多様な分析関数と強力なファセット機能の両方を通じて、さまざまな方法でデータと対話することを可能にします。標準ファセットは、分析機能を活用した追加機能とともに、分析コンポーネント内でサポートされています。
モジュール
これは、使用する前に有効にする必要がある `analytics` Solr モジュールによって提供されます。
分析構成
分析フレームワークは*検索コンポーネント*であるため、そのように宣言し、検索ハンドラに追加する必要があります。
クラウドコレクションに対する分散分析リクエストの場合、コンポーネントはシャード間通信に厳密に `AnalyticsHandler` を使用します。分析ハンドラは、ユーザーが分析リクエストを送信するために使用されるべきではありません。
次に、リクエストハンドラと検索コンポーネントを登録する必要があります。`solrconfig.xml` に、他のリクエストハンドラの定義付近に次の行を追加します。
<!-- To handle user requests -->
<searchComponent name="analytics" class="org.apache.solr.handler.component.AnalyticsComponent" />
<requestHandler name="/select" class="solr.SearchHandler">
<arr name="last-components">
<str>analytics</str>
</arr>
</requestHandler>
<!-- For inter-shard communication during distributed requests -->
<requestHandler name="/analytics" class="org.apache.solr.handler.AnalyticsHandler" />
これらの変更を有効にするには、Solr を再起動するか、コアまたはコレクションをリロードします。
リクエスト構文
分析リクエストは、検索ハンドラに送信されたリクエストのパラメータ `analytics` を使用して Solr に渡されます。分析リクエストは検索ハンドラリクエスト内で送信されるため、検索ハンドラによって決定された結果セットに基づいて結果を計算します。
たとえば、この curl コマンドは、単純な分析リクエストをエンコードして検索ハンドラに POST します。
$ curl --data-binary 'analytics={
"expressions" : {
"revenue" : "sum(mult(price,quantity))"
}
}'
https://127.0.0.1:8983/solr/sales/select?q=*:*&wt=json&rows=0
分析リクエストには、主に 3 つの部分があります。
- 式
-
結果セット全体に対して実行する計算のリスト。式は、検索結果を集計して返す単一の値にします。このリストは、各グループで定義されている式とは完全に独立しています。式のセクションで詳細をご覧ください。
- 関数
-
リクエスト全体で使用される 1 つ以上の 変数関数。これらは本質的にラムダ関数であり、さまざまな方法で組み合わせることができます。これらの関数は、`expressions` と `groupings` で定義された式に使用されます。
- グループ化
-
式に加えて計算する グループ化 のリスト。グループ化には、一連のファセットと、それらのファセットに対して計算する式のリストが含まれます。グループ化で定義された式は、そのグループ化で定義されたファセットに対してのみ計算されます。
オプションパラメータ `expressions` または `groupings` パラメータのいずれかがリクエストに存在する必要があります。そうでない場合、計算する分析はありません。`functions` パラメータは常にオプションです。 |
{
"functions": {
"sale()": "mult(price,quantity)"
},
"expressions" : {
"max_sale" : "max(sale())",
"med_sale" : "median(sale())"
},
"groupings" : {
"sales" : {
"expressions" : {
"stddev_sale" : "stddev(sale())",
"min_price" : "min(price)",
"max_quantity" : "max(quantity)"
},
"facets" : {
"category" : {
"type" : "value",
"expression" : "fill_missing(category, 'No Category')",
"sort" : {
"criteria" : [
{
"type" : "expression",
"expression" : "min_price",
"direction" : "ascending"
},
{
"type" : "facetvalue",
"direction" : "descending"
}
],
"limit" : 10
}
},
"temps" : {
"type" : "query",
"queries" : {
"hot" : "temp:[90 TO *]",
"cold" : "temp:[* TO 50]"
}
}
}
}
}
}
式
式は、分析コンポーネントから情報を要求する方法です。これらは、計算してレスポンスで返す統計式です。
式の構築
式の構成要素
式は、フィールド、定数、マッピング関数、および集約関数を使用して構築されます。これらの定義方法を以下に説明します。
- ソース
-
-
定数: 式で定義された値。サポートされている定数の型は、定数セクションで説明されています。
-
フィールド: インデックスから読み取られるSolrフィールド。サポートされているフィールドは、サポートされているフィールドタイプセクションにリストされています。
-
- マッピング関数
-
マッピング関数は、各Solrドキュメントまたは集約の値をマッピングします。提供されるマッピング関数の詳細は、分析マッピング関数に記載されています。
-
非集約マッピング: 別のフィールドまたは定数を持つフィールドをマッピングすると、すべてのSolrドキュメントの値が返されます。非集約マッピング関数は、入力としてフィールド、定数、および他の非集約マッピング関数を取ることができます。
-
集約マッピング: 集約関数を別の集約関数または定数でマッピングすると、単一の値が返されます。
-
- 集約関数
-
すべてのSolrドキュメントのソースおよび/または非集約マッピング関数の値を単一の値に集約する関数。提供される集約関数の詳細は、分析集約関数に記載されています。
コンポーネントの順序
有効な式を作成するには、式のコンポーネントを次の順序で使用してください。
-
集約マッピング関数
-
定数
-
集約関数
-
ソース
-
非集約マッピング関数
-
ソース
-
非集約マッピング関数
-
-
-
集約マッピング関数
-
-
集約関数
この順序は、次のルールに基づいています。
-
集約関数を別の集約関数の引数にすることはできません。すべての集約は1つのステップでまとめて行われるため、1つの集約関数は別の集約関数の結果に依存できません。
-
分析コンポーネントは式に対して値のリスト(ドキュメントごとに1つ)を返すことができないため、フィールドを集約されていないままにすることはできません。すべての式は単一の値に集約する必要があります。
-
関数の作成時にマッピング関数は必須ではありませんが、必要に応じてネストされたマッピングをいくつでも使用できます。
-
ネストされたマッピング関数は同じ型である必要があるため、どちらも非集約であるか、どちらも集約である必要があります。集約マッピング関数は、非集約マッピング関数をパラメーターとして使用することはできず、その逆も同様です。
構築例
上記の定義と順序を使用して、式の例をコンポーネントに分解できます。
div(sum(a,fill_missing(b,0)),add(10.5,count(mult(a,c)))))
全体として、これは集約マッピング関数です。 `div` 関数は、提供されているマッピング関数であり、引数が集約されているため、集約マッピング関数です。
式をさらに分解すると
-
`sum(a,fill_missing(b,0))`:集約関数
`sum` は、提供されている集約関数です。-
`a`:フィールド
-
`fill_missing(b,0)`:非集約マッピング関数
`fill_missing` は、提供されているマッピング関数であり、フィールド引数を持つため、非集約マッピング関数です。-
`b`:フィールド
-
`0`:定数
-
-
-
`add(10.5,count(mult(a,c)))`:集約マッピング関数
`add` は、提供されているマッピング関数であり、集約関数引数を持つため、集約マッピング関数です。-
`10.5`:定数
-
`count(mult(a,c))`:集約関数
`count` は、提供されている集約関数です。-
`mult(a,c)`:非集約マッピング関数
`mult` は、提供されているマッピング関数であり、2つのフィールド引数を持つため、非集約マッピング関数です。-
`a`:フィールド
-
`c`:フィールド
-
-
-
式のカーディナリティ(複数値と単一値)
すべての複数値式のルートは、複数値フィールドです。単一値式は、定数または単一値フィールドで始めることができます。すべての単一値式は、1つの値を含む複数値式として扱うことができます。
単一値式と複数値式は、多くのマッピング関数で一緒に使用できます。また、複数値式を単独で使用したり、多くの単一値式を一緒に使用したりすることもできます。例えば
add(<単一値double>、<単一値double>、…)
-
各式の値の値が加算された単一値double式を返します。
add(<単一値double>、<複数値double>)
-
2番目の式の各値が最初の式の単一の値に加算された複数値double式を返します。
add(<複数値double>、<単一値double>)
-
上記の関数と同じように動作します。
add(<複数値double>)
-
パラメーター式の複数の値の合計である単一値double式を返します。
型と暗黙のキャスト
新しい分析コンポーネントは、現在、以下の表にリストされている型をサポートしています。これらの型には、次の関係に対して一方向の暗黙的キャストが有効になっています。
型 | 暗黙的にキャストされる型 |
---|---|
ブール値 |
文字列 |
日付 |
Long、文字列 |
整数 |
Long、Float、Double、文字列 |
Long |
Double、文字列 |
Float |
Double、文字列 |
Double |
文字列 |
文字列 |
なし |
暗黙のキャストとは、関数がパラメーターとして特定の型の値を必要とする場合、可能な場合は引数が自動的にその型に変換されることを意味します。
たとえば、`concat()` は文字列パラメーターのみを受け入れ、すべての型は文字列に暗黙的にキャストできるため、任意の型が引数として受け入れられます。
これは、動的に型付けされた関数にも当てはまります。 `fill_missing()` は、同じ型の2つの引数を必要とします。ただし、同じ型に暗黙的にキャストされる2つの型も使用できます。
たとえば、`fill_missing(<long>,<float>)` は、longをfloatに暗黙的にキャストできず、floatをlongに暗黙的にキャストできないため、`fill_missing(<double>,<double>)` にキャストされます。
暗黙のキャストには順序があり、より特殊な型はより一般的な型よりも前に順序付けられます。そのため、longとfloatはどちらもdoubleとstringに暗黙的にキャストできますが、doubleにキャストされます。これは、doubleが、すべての型がキャストできるstringよりも特殊な型であるためです。
順序は、上記の表での順序と同じです。
カーディナリティも暗黙的にキャストできます。すべての単一値式は1つの値を持つ複数値式であるため、単一値式は常に複数値式に暗黙的にキャストできます。
暗黙のキャストは、式がそれなしでは「コンパイル」されない場合にのみ発生します。式が最初にすべての型付けルールに従っている場合、暗黙のキャストは発生しません。 `string()`、`date()`、`round()`、`floor()`、`ceil()` などの特定の関数は、明示的なキャストとして機能し、必要な型を宣言します。ただし、`round()`、`floor()`、`cell()` は、引数の型に応じて、intまたはlongのいずれかを返すことができます。
変数関数
変数関数は、式を短縮し、分析クエリの記述を容易にする方法です。これらは本質的にリクエストで定義されたラムダ関数です。
{
"functions" : {
"sale()" : "mult(price,quantity)"
},
"expressions" : {
"max_sale" : "max(sale())",
"med_sale" : "median(sale())"
}
}
上記のリクエストでは、`mult(price,quantity)` を2回記述する代わりに、この考え方を抽象化するために関数 `sale()` が定義されました。次に、その関数が複数の式で使用されました。
特定のカテゴリの売上を確認したいとします。
{
"functions" : {
"clothing_sale()" : "filter(mult(price,quantity),equal(category,'Clothing'))",
"kitchen_sale()" : "filter(mult(price,quantity),equal(category,\"Kitchen\"))"
},
"expressions" : {
"max_clothing_sale" : "max(clothing_sale())"
, "med_clothing_sale" : "median(clothing_sale())"
, "max_kitchen_sale" : "max(kitchen_sale())"
, "med_kitchen_sale" : "median(kitchen_sale())"
}
}
引数
カテゴリごとに関数を作成する代わりに、`category` を `sale()` 関数への入力として使用する方がはるかに簡単です。この機能の例を以下に示します。
{
"functions" : {
"sale(cat)" : "filter(mult(price,quantity),equal(category,cat))"
},
"expressions" : {
"max_clothing_sale" : "max(sale(\"Clothing\"))"
, "med_clothing_sale" : "median(sale('Clothing'))"
, "max_kitchen_sale" : "max(sale(\"Kitchen\"))"
, "med_kitchen_sale" : "median(sale('Kitchen'))"
}
}
変数関数は、任意の数の引数を取り、それらをフィールドまたは定数であるかのように関数式で使用できます。
可変長引数
可変量のパラメーターを取る分析関数があります。そのため、変数関数が可変量のパラメーターを取る必要があるユースケースがあります。
たとえば、製品の価格に複数の、まだ決定されていない数のコンポーネントがある場合があります。最後のパラメーターの後に `..` が続く場合、関数は可変長のパラメーターを取ることができます。
{
"functions" : {
"sale(cat, costs..)" : "filter(mult(add(costs),quantity),equal(category,cat))"
},
"expressions" : {
"max_clothing_sale" : "max(sale('Clothing', material, tariff, tax))"
, "med_clothing_sale" : "median(sale('Clothing', material, tariff, tax))"
, "max_kitchen_sale" : "max(sale('Kitchen', material, construction))"
, "med_kitchen_sale" : "median(sale('Kitchen', material, construction))"
}
}
上記の例では、可変長引数を使用して、製品に使用するすべてのコストをカプセル化しています。可変長パラメーターに要求される引数の明確な数はないため、衣料品の式は3を使用でき、台所の式は2を使用できます。 `sale()` 関数が呼び出されると、`costs` は指定された引数に展開されます。
したがって、上記のリクエストでは、`sale` 関数内で
-
add(costs)
は、次の両方に展開されます。
-
add(material, tariff, tax)
-
add(material, construction)
For-Each関数
高度な機能
次の関数の詳細は、高度なリクエスト用です。 |
上記の機能では、未定義数の引数を関数に渡すことができますが、それらの引数を操作することはできません。
多くの場合、各引数を追加の関数でラップしたい場合があります。たとえば、複数のカテゴリを同時に見たい場合があります。そのため、`category EQUALS x **OR** category EQUALS y` などを確認したいと考えています。
これを行うには、可変長パラメーターの各値を変換するfor-eachラムダ関数を使用する必要があります。 for-eachは、可変長パラメーターの後に `:` 文字で開始されます。
{
"functions" : {
"sale(cats..)" : "filter(mult(price,quantity),or(cats:equal(category,_)))"
},
"expressions" : {
"max_sale_1" : "max(sale('Clothing', 'Kitchen'))"
, "med_sale_1" : "median(sale('Clothing', 'Kitchen'))"
, "max_sale_2" : "max(sale('Electronics', 'Entertainment', 'Travel'))"
, "med_sale_2" : "median(sale('Electronics', 'Entertainment', 'Travel'))"
}
}
この例では、`cats:` はすべてのパラメーター `cats` に対してfor-eachラムダ関数を開始する構文であり、`_` 文字はfor-eachの各反復で `cats` の値を参照するために使用されます。 `sale("Clothing", "Kitchen")` が呼び出されると、ラムダ関数 `equal(category,_)` が `or()` 関数内でClothingとKitchenの両方に適用されます。
これらのルールをすべて使用すると、式
`sale("Clothing","Kitchen")`
はに展開されます
`filter(mult(price,quantity),or(equal(category,"Kitchen"),equal(category,"Clothing")))`
式パーサーによって。
グルーピングとファセット
ファセットは、Solrの他の部分と同様に、分析結果を、式が計算されるデータの属性によって分割し、グループ化することを可能にします。
現在、分析コンポーネントで使用可能なファセットは、値ファセット、ピボットファセット、範囲ファセット、クエリファセットです。各ファセットは、定義されているグルーピング内で一意の名前を持つ必要があり、グルーピング外でファセットを定義することはできません。
グルーピングを使用すると、一連のファセットに対して同じ式のグループを計算できます。グルーピングには、expressions
とfacets
の両方が指定されている必要があります。
{
"functions" : {
"sale()" : "mult(price,quantity)"
},
"groupings" : {
"sales_numbers" : {
"expressions" : {
"max_sale" : "max(sale())",
"med_sale" : "median(sale())"
},
"facets" : {
"<name>" : "< facet request >"
}
}
}
}
{
"analytics_response" : {
"groupings" : {
"sales_numbers" : {
"<name>" : "< facet response >"
}
}
}
}
ファセットのソート
一部の分析ファセットでは、結果を複雑にソートできます。現在ソート可能なファセットは、分析値ファセットと分析ピボットファセットの2つです。
パラメータ
criteria(基準)
-
必須
デフォルト:なし
ファセットをソートするための基準のリスト。
以下のパラメータを取ります。
type(タイプ)
-
必須
デフォルト:なし
ソートのタイプ。2つの値が可能です。*
expression
:同じグルーピングで定義された式の値でソートします。*facetvalue
:ファセット値の文字列表現でソートします。 Direction(方向)
-
オプション
デフォルト:
ascending
(昇順)ソート方向。オプションは
ascending
(昇順)またはdescending
(降順)です。 expression(式)
-
オプション
デフォルト:なし
type
がexpression
の場合、同じグルーピングで定義された式の名称。
limit(制限)
-
オプション
デフォルト:
-1
返されるファセット値の数を上位 *N* 個に制限します。デフォルトは制限がないことを意味します。
offset(オフセット)
-
オプション
デフォルト:
0
制限が設定されている場合、上位 *N* 個のファセット値をスキップします。
{
"criteria" : [
{
"type" : "expression",
"expression" : "max_sale",
"direction" : "ascending"
},
{
"type" : "facetvalue",
"direction" : "descending"
}
],
"limit" : 10,
"offset" : 5
}
値ファセット
値ファセットは、各ドキュメントに適用されるマッピング式の値によってドキュメントをグループ化するために使用されます。マッピング式は、集約関数を含まない式です。
詳細については、式セクションを参照してください。例えば
-
mult(quantity, sum(price, tax))
:生成された収益によってドキュメントを分割します。 -
fillmissing(state, "N/A")
:州ごとにドキュメントを分割します。ドキュメントに州が含まれていない場合は「N/A」が使用されます。
値ファセットはソートできます。
パラメータ
expression(式)
-
必須
デフォルト:なし
各ドキュメントのファセットバケットを選択するための式。
sort(ソート)
-
オプション
デフォルト:なし
ピボットの結果に対するソート。
{
"type" : "value",
"expression" : "fillmissing(category,'No Category')",
"sort" : {}
}
[
{ "..." : "..." },
{
"value" : "Electronics",
"results" : {
"max_sale" : 103.75,
"med_sale" : 15.5
}
},
{
"value" : "Kitchen",
"results" : {
"max_sale" : 88.25,
"med_sale" : 11.37
}
},
{ "..." : "..." }
]
これは、元の分析コンポーネントに存在していたフィールドファセットの代替です。フィールドファセットの機能は、フィールドの名前を式として使用することにより、値ファセットで維持されます。 |
分析ピボットファセット
ピボットファセットは、各ドキュメントに適用される複数のマッピング式の値によってドキュメントをグループ化するために使用されます。
ピボットファセットは、値ファセットのレイヤーのように機能します。ピボットのリストが必要であり、リストの順序は返される結果に直接影響します。指定された最初のピボットは、通常の値ファセットのように扱われます。指定された2番目のピボットは、最初のピボットの各値に対して1つの値ファセットのように扱われます。これらの2番目のレベルの値ファセットはそれぞれ、最初のレベルのファセットバケット内のドキュメントに制限されます。これは、指定されたピボットの数だけ続きます。
ソートは、ピボットごとに有効になります。つまり、トップピボットのソートに`limit:1`が設定されている場合、ファセットの最初の値のみがドリルダウンされます。各ピボットのソートは、他のピボットとは独立しています。
パラメータ
pivots(ピボット)
-
必須
デフォルト:なし
ドリルダウンファセットを計算するためのピボットのリスト。リストは、最上位レベルから最下位レベルの順に並べられています。
name(名前)
-
必須
デフォルト:なし
ピボットの名前。
expression(式)
-
必須
デフォルト:なし
各ドキュメントのファセットバケットを選択するための式。
sort(ソート)
-
オプション
デフォルト:なし
ピボットの結果に対するソート。
{
"type" : "pivot",
"pivots" : [
{
"name" : "country",
"expression" : "country",
"sort" : {}
},
{
"name" : "state",
"expression" : "fillmissing(state, fillmissing(providence, territory))"
},
{
"name" : "city",
"expression" : "fillmissing(city, 'N/A')",
"sort" : {}
}
]
}
[
{ "..." : "..." },
{
"pivot" : "Country",
"value" : "USA",
"results" : {
"max_sale" : 103.75,
"med_sale" : 15.5
},
"children" : [
{ "..." : "..." },
{
"pivot" : "State",
"value" : "Texas",
"results" : {
"max_sale" : 99.2,
"med_sale" : 20.35
},
"children" : [
{ "..." : "..." },
{
"pivot" : "City",
"value" : "Austin",
"results" : {
"max_sale" : 94.34,
"med_sale" : 17.60
}
},
{ "..." : "..." }
]
},
{ "..." : "..." }
]
},
{ "..." : "..." }
]
分析範囲ファセット
範囲ファセットは、フィールドの値によってドキュメントを指定された範囲セットにグループ化するために使用されます。分析範囲ファセットへの入力は、Solr範囲ファセットで使用される入力と同じです。使用方法の詳細については、範囲ファセットセクションを参照してください。
パラメータ
field (フィールド)
-
必須
デフォルト:なし
ファセット対象のフィールド。
start (開始)
-
必須
デフォルト:なし
範囲の下限。
end (終了)
-
必須
デフォルト:なし
範囲の上限。
gap (間隔)
-
必須
デフォルト:なし
ファセットバケットを生成するための範囲間隔のリスト。バケットが`start`から`end`の範囲に収まらない場合、最後の`gap`値が必要な回数だけ繰り返されて、未使用の範囲が埋められます。
hardend (固定終了)
-
オプション
デフォルト:`false`
最後のファセットバケット範囲が`end`値を超えた場合に、`end`値で切り捨てるかどうか。
include (含める)
-
オプション
デフォルト:`lower` (下限)
ファセットバケットに含める境界。* `lower` - すべてのギャップベースの範囲に下限が含まれます。* `upper` - すべてのギャップベースの範囲に上限が含まれます。* `edge` - 最初と最後のギャップ範囲には、対応する上限/下限オプションが指定されていない場合でも、エッジ境界(最初の範囲には下限、最後の範囲には上限)が含まれます。* `outer` - `before`および`after`範囲には、最初または最後の範囲に既にこれらの境界が含まれている場合でも、境界が含まれます。* `all` - すべてのオプション (`lower`、`upper`、`edge`、`outer`) が含まれます。
others (その他)
-
オプション
デフォルト:`none` (なし)
ファセットに含める追加の範囲。* `before` - フィールド値が最初の範囲の下限よりも小さいすべてのレコード。* `after` - フィールド値が最後の範囲の上限よりも大きいすべてのレコード。* `between` - フィールド値が最初の範囲の下限と最後の範囲の上限の間にあるすべてのレコード。* `none` - 上記のいずれのファセットバケットも含まれません。* `all` - `before`、`after`、`between` のファセットバケットを含めます。
{
"type" : "range",
"field" : "price",
"start" : "0",
"end" : "100",
"gap" : [
"5",
"10",
"10",
"25"
],
"hardend" : true,
"include" : [
"lower",
"upper"
],
"others" : [
"after",
"between"
]
}
[
{
"value" : "[0 TO 5]",
"results" : {
"max_sale" : 4.75,
"med_sale" : 3.45
}
},
{
"value" : "[5 TO 15]",
"results" : {
"max_sale" : 13.25,
"med_sale" : 10.20
}
},
{
"value" : "[15 TO 25]",
"results" : {
"max_sale" : 22.75,
"med_sale" : 18.50
}
},
{
"value" : "[25 TO 50]",
"results" : {
"max_sale" : 47.55,
"med_sale" : 30.33
}
},
{
"value" : "[50 TO 75]",
"results" : {
"max_sale" : 70.25,
"med_sale" : 64.54
}
},
{ "..." : "..." }
]
クエリファセット
クエリファセットは、指定されたクエリのセットによってドキュメントをグループ化するために使用されます。
パラメータ
queries (クエリ)
-
必須
デフォルト:なし
ファセットするクエリのリスト。
{
"type" : "query",
"queries" : {
"high_quantity" : "quantity:[ 5 TO 14 ] AND price:[ 100 TO * ]",
"low_quantity" : "quantity:[ 1 TO 4 ] AND price:[ 100 TO * ]"
}
}
[
{
"value" : "high_quantity",
"results" : {
"max_sale" : 4.75,
"med_sale" : 3.45
}
},
{
"value" : "low_quantity",
"results" : {
"max_sale" : 13.25,
"med_sale" : 10.20
}
}
]