2017-12-01 1 views
1

ich eine Facette Feld bin Abfrage, die wie folgt aussieht:SOLR - Auftrag Facette Werte case-insentive während des ursprünglichen Wertes in Facette Ergebnis Erhaltung

<field name="brand" type="string" indexed="true" stored="false /> 

Die string Typdefinition:

<fieldType name="string" class="solr.StrField" sortMissingLast="true" docValues="true"/> 

I Sortieren Sie die Facettenwerte basierend auf index: f.brand.facet.sort=index.

Das gibt mir ein Ergebnis wie folgt aus:

Aaaa (5) 
Bbbb (14 
Cccc (8) 
abbb (29) 

Ich möchte die Werte Groß- und Kleinschreibung sortieren, so dass ich versuchte, ein neues fieldType mit LowerCaseFilterFactory zu machen:

<fieldType name="text_facet" class="solr.TextField"> 
    <analyzer type="index"> 
     <tokenizer class="solr.KeywordTokenizerFactory"/> 
     <filter class="solr.LowerCaseFilterFactory"/> 
    </analyzer> 
    <analyzer type="query"> 
     <tokenizer class="solr.KeywordTokenizerFactory"/> 
     <filter class="solr.LowerCaseFilterFactory"/> 
    </analyzer> 
</fieldType> 

Nach reindexing das Ergebnis sieht so aus:

aaaa (5) 
abbb (29) 
bbbb (14) 
cccc (8) 

Die Reihenfolge ist cor rect, aber die Werte sind jetzt auch LowerCase.

würde ich dieses Ergebnis mag:

Aaaa (5) 
abbb (29) 
Bbbb (14) 
Cccc (8) 

Die meisten Beiträge mir hier erzählen eine copyField zu schaffen, aber ich verstehe nicht, wie ich die beiden Felder kombinieren kann, wenn es um facetten Abfragen kommt.

Gibt es eine Möglichkeit, Facettenwerte nach Groß-/Kleinschreibung zu sortieren, während der ursprüngliche Wert bei der Abfrage beibehalten wird?

+0

Erhalten Sie immer alle Facetteneinträge? I.e. Könnten Sie die Kundenseite sortieren? – MatsLindh

+0

@MatsLindh Nein, bin ich nicht. Ich bin auf der Suche nach einem eleganten Weg, Solr das Sortieren zu überlassen. – Rob

+0

Dann glaube ich nicht, dass Sie eine perfekte Lösung haben werden, wenn Sie nur die Facetten von Solr verwenden (es könnte möglich sein, etwas zusammen mit Streaming-Ausdrücken zu hacken). Payloads mit Facetting könnten das vielleicht lösen, aber das ist momentan noch nicht implementiert. Eine andere Möglichkeit ist, die Werte mit der unteren Form und einem Trennzeichen zu versehen (zB Index 'aaaa; Aaaa' und' bbbb; Bbbb ', dann durch dieses Trennzeichen in Ihrem Frontend splitten.Dies würde verschiedene Zählungen für verschiedene Gehäuse geben, aber das ist vielleicht kein Problem/könnte auf jeden Fall erwünscht sein .. – MatsLindh

Antwort

1

Zuallererst gibt es keine direkte Möglichkeit, dies zu tun. Ich denke, der Vorschlag, copyField zu verwenden, ist etwas anderes, aber ich könnte möglicherweise, könnte es helfen.

Die Idee ist folgende: Sie Marke Felder vom Typ string erstellen, als Sie copyField mit Kleinschreibung haben.

<field name="brand" type="string" indexed="true" stored="false"/> 
<field name="brand_text" type="text_facet" indexed="true" stored="false"/> 
<fieldType name="string" class="solr.StrField" sortMissingLast="true" docValues="true"/> 

<fieldType name="text_facet" class="solr.TextField"> 
     <analyzer type="query"> 
      <tokenizer class="solr.KeywordTokenizerFactory"/> 
      <filter class="solr.LowerCaseFilterFactory"/> 
     </analyzer> 
</fieldType> 

<copyField source="brand" dest="brand_text" /> 

Während der Abfragezeit abfragen Sie einfach beide Felder für Facettierung - in Ihrem Fall ist es so etwas wie dies sein wird (ich habe einige Dokumente hinzugefügt):

brand:[Aaaa (1), Bbbb (1), Cccc (1), aBbb (1), abbb (1)] 
brand_text:[aaaa (1), abbb (2), bbbb (1), cccc (1)] 

Sobald Sie bekommen das Sortieren durch brand_text, konnten Sie die ursprünglichen Facettenwerte erhalten und irgendwie angemessene Antwort liefern.

Ich möchte jedoch darauf hinweisen, dass ähnliche niedrige Werte gemischt werden könnten. In unserem Fall ist es sowohl ABbb als auch abbb, die im Kleinbuchstabenmodus genau gleich sind, also ist die Frage, was Sie dort zeigen möchten, also denke ich, dass es auf der Geschäftslogikseite richtig gehandhabt werden sollte.

Vollständig korrekte Lösung konnte durch Erweitern org.apache.solr.handler.component.FacetComponent, die für Solr Facettierung verantwortlich ist, erreicht werden.Es gibt einen Code, der Sortierung zu tun ist:

 boolean countSorted = dff.sort.equals(FacetParams.FACET_SORT_COUNT); 
     if (countSorted) { 
     counts = dff.countSorted; 
     if (counts == null || dff.needRefinements) { 
      counts = dff.getCountSorted(); 
     } 
     } else if (dff.sort.equals(FacetParams.FACET_SORT_INDEX)) { 
     counts = dff.getLexSorted(); 
     } else { // TODO: log error or throw exception? 
     counts = dff.getLexSorted(); 
     } 

und getLexSorted ist genau das, was die Begriffe ist das Sortieren:

Arrays.sort(arr, (o1, o2) -> o1.indexed.compareTo(o2.indexed)); 

und Sie müssen nur beide toLowerCase()-o1 und o2 anzuwenden. Dieser Ansatz wird jedoch viel schwieriger - Sie müssen implementieren (erweitern Sie vorhandene FacetComponent und später aktivieren Sie es in Ihrer solrconfig.xml, einschließlich CI usw. usw.)

+0

Vielen Dank für die Antwort, das ist genau das, was ich dachte 2 verschiedene Facettenfelder sind fehleranfällig und skalieren nicht gut (da ich entweder den ursprünglichen Markennamen im Auge behalten würde oder ALLE Facettenwerte abfragen müsste). Ich glaube nicht, dass es für mich machbar ist, die ' FacetComponent' Klasse, aber wird es sich ansehen, da es aussieht, als wäre es die eleganteste Art. – Rob

+0

@Rob, leider, das ist die einzige Möglichkeit, auf der Solr-Seite zu handeln. Normalerweise müssen Sie nur Markennamen behalten (nur als ein Beispiel) konsistentes ac ross ganzer Katalog in irgendeiner bevorzugten Form. – Mysterion

+0

Es gibt wirklich keine Möglichkeit, Markennamen konsistent zu halten, da sie Namen sind und ich kann CamelCasing nicht einfach einen markenrechtlich geschützten Namen starten. – Rob