このようなデータを含むフィールドがあります。行の例を次に示します。
ロンドン;グレーター ロンドン;ロンドン シティ
次のファセットで終わりたいと思います
ロンドン (カウント 10) グレーター ロンドン (カウント 5) ロンドン シティ (カウント 2)
使用する適切なクエリについては、私は立ち往生しています。
Solr は 1 つのフィールド内に複数のファセットを持つことができますか?
乾杯
k
2 つのオプションがあります。
最善の方法は、多値フィールドを使用することです。つまり、セミコロンに入ってくるコンテンツを分割する必要があります。これは、データの取得方法によって異なります。たとえば、CSV では、フィールドを複数値として宣言し、セミコロンで分割することができます。DataImportHandler には、コンテンツを吐き出すこともできる RegexTransformer があります。または、任意のソースに適用できる Request Processor を使用することもできますが、すぐに使える分割はないと思います。1つ書く必要があります。
もう 1 つのオプションは、ファセット フィールドが格納された値ではなくトークン化された値を使用することを理解することです。通常、文字列として定義されているようにファセットされたフィールドは、まさにそのためです。ただし、最初のアプローチがまったく機能しない場合 (そして、努力する必要があります) は、トークンをセミコロンで分割するだけで他の処理を行わない特別なフィールド タイプを構成できます。そのためにPatternTokenizerFactoryを使用します。
Alexandre Rafalovitch の提案に基づいて、かなり良いオプションを見つけました。Java に取り掛かる代わりに、簡単な JavaScript をいくつか作成し、それを StatelessScriptUpdateProcessorFactory から呼び出しました。私の場合、このように分割する必要があるフィールドがいくつかあるため、コードの一部はそれを反映しています。
また、これは基本的にプロトタイプ コードであることも指摘しておく必要があります。おそらく、少し時間をかけて改善したり、構成を簡単にしたりしたいと思うでしょう。私はそうするでしょう! しかし、それを終える頃には、おそらくこの質問を更新するのを忘れているでしょう。ハックな回答は、まったく回答がないよりはましだと思います。:-) (完了したら、戻ってきて更新することを忘れないようにしますが...)
ここで、solrconfig.xml に updateRequestProcessingChain を追加しました。
<updateRequestProcessorChain name="splitting">
<processor class="solr.StatelessScriptUpdateProcessorFactory">
<str name="script">split-script.js</str>
<lst name="params">
<str name="splitFields">firstfield,secondfield</str>
</lst>
</processor>
<processor class="solr.RunUpdateProcessorFactory" />
</updateRequestProcessorChain>
これを の「デフォルト」構成にも追加しました/update/extract
。
<str name="update.chain">splitting</str>
split-script.js については、既にフォルダーにあるサンプルの update-script.js をコピーし、関数conf
を変更しました。processAdd
function processAdd(cmd) {
doc = cmd.solrDoc; // org.apache.solr.common.SolrInputDocument
id = doc.getFieldValue("id");
logger.info("splitter-script#processAdd: id=" + id);
fields_param = params.get('splitFields'); // "params" only exists if processor configured with <lst name="params">
fields = fields_param.split(',');
for (var i = 0; i < fields.length; i++)
{
var fieldName = fields[i];
var field = doc.getField(fieldName);
if (field)
{
var value = field.getValue();
if (value)
{
// Remove the old field so the un-split value doesn't also show up in the list...
doc.removeField(fieldName);
doc.addField(fieldName, value.split(';'));
}
}
}
}
私のために働いているようですが、他の人にも役立つことを願っています!