2016-06-04 6 views
0

Ich habe versucht, von Hibernate Search 5.5.2 zu 5.5.3 zu migrieren, und ich habe ein Problem mit einem meiner Sortierfelder aufgetreten. Dies ist der Code, der mit 5.5.2 funktioniert (oder vielleicht war es nicht funktioniert, und war einfach nicht Fehler werfen?)Hibernate Search 5.5.3 - Sortieren nach Collection-Größe funktioniert nicht mehr

public class CollectionCountBridge implements MetadataProvidingFieldBridge { 

    @Override 
    public void configureFieldMetadata(String name, FieldMetadataBuilder builder) { 
     builder.field(name, FieldType.INTEGER).sortable(true); 
    } 

    @Override 
    public void set(String name, Object object, Document document, LuceneOptions luceneOptions) { 
     if (object == null || (!(object instanceof Collection))) { 
      return; 
     } 
     Collection<?> coll = (Collection<?>) object; 
     int size = coll.size(); 

     IntField field = new IntField(name, size, (luceneOptions.getStore() != Store.NO) ? Field.Store.YES : Field.Store.NO); 
     document.add(field); 
    } 

} 

... 

@Field(analyze = Analyze.NO, norms = Norms.YES, index = Index.YES) 
@FieldBridge(impl = CollectionCountBridge.class) 
@IndexedEmbedded 
@OneToMany 
public Set<MyCollection> getMyCollection() { 
    return myCollection; 
} 

Der Code im Wesentlichen speichert die Größe der Sammlung als sortierbar Feld. Dies basierte auf der Dokumentation, die vorschlug, wenn ich ein sortierbares Feld über eine Brücke definieren muss, dann muss ich MetadataProvidingFieldBridge implementieren, um es sortierbar zu markieren. Die Dokumentation zeigt jedoch nur ein Beispiel für ein String-Feld, während ich ein numerisches Feld verwenden muss. http://docs.jboss.org/hibernate/search/5.5/reference/en-US/html_single/#sortablefield-annotation

So nach dem Upgrade auf 5.5.3 begann ich Fehler wie immer:

org.hibernate.search.exception.SearchException: HSEARCH000307: Sort type INT is not compatible with string type of field 'myCollection' 

Ich habe versucht, das Feld zu dem Dokument in einer Vielzahl von Möglichkeiten geben, und nichts scheint zu funktionieren. Einige Dinge, die ich habe versucht:

luceneOptions.addNumericFieldToDocument(name, size, document); 

document.add(new SortedNumericDocValuesField(name, size)); 
//this throws an error on index 
java.lang.IllegalArgumentException: cannot change DocValues type from SORTED_NUMERIC to NUMERIC for field "myCollection" 

public class CollectionCountBridge extends NumberBridge 

Also, meine Frage ist, was ist der richtige Weg, ein sortierbare numerisches Feld mit dem Index, über eine Brücke, wie von 5.5.3 hinzufügen?

Antwort

1

In der Tat ist es kein Fehler.

Sie müssen Ihrem Dokument ein entsprechendes NumericDocValuesField hinzufügen, um die Sortierung zu aktivieren. Wir werden das in Zukunft verbessern, aber das müssen Sie jetzt tun.

Darüber hinaus würde ich nicht empfehlen, das Feld mit dem gleichen Namen wie dem Standardfeld hinzuzufügen, Sie sollten die Sammlungsgröße besser mit einem anderen Feldnamen indizieren.

Ihre FieldBridge sollte wie folgt aussehen:

public class CollectionCountBridge implements MetadataProvidingFieldBridge { 
    private static final String COUNT_SUFFIX = "_count"; 

    @Override 
    public void configureFieldMetadata(String name, FieldMetadataBuilder builder) { 
     builder.field(name + COUNT_SUFFIX, FieldType.INTEGER).sortable(true); 
    } 

    @Override 
    public void set(String name, Object object, Document document, LuceneOptions luceneOptions) { 
     if (object == null || (!(object instanceof Collection))) { 
      return; 
     } 
     Collection<?> coll = (Collection<?>) object; 
     int size = coll.size(); 

     luceneOptions.addNumericFieldToDocument(name + COUNT_SUFFIX, size, document); 
     document.add(new NumericDocValuesField(name + COUNT_SUFFIX, size.longValue())); 
    } 
} 

Und beim Sortieren, verwenden Sie einen neuen SortField ("myCollection_count", SortField.Type.LONG)).

+0

Vielen Dank, es scheint alles gut zu funktionieren! – mharray

1

Es scheint, dass Sie hier einen Fehler gefunden haben. Bei einer benutzerdefinierten Brücke können wir den numerischen Codierungstyp nicht richtig erkennen. Ich habe HSEARCH-2292 dafür abgelegt.

Als eine Problemumgehung können Sie eine vorübergehende Eigenschaft in Ihrer Entität erstellen, die die Auflistungsgröße verfügbar macht. Zu dieser Eigenschaft fügen Sie @Field und @SortableField hinzu, die dem Index die erforderlichen Felder mit den richtigen Typen hinzufügen sollten.