5 Stimmen

Reihenfolge der Abfrageergebnisse nach startswith match

Wir führen eine Site-Suche durch, bei der wir ein Feld mit einem icontains . Es funktioniert gut, aber die Ergebnisse, die angezeigt werden, haben nicht das relevanteste Ergebnis an der Spitze.

Ein Beispiel ist die Suche nach "Game of Thrones". Wenn die Suche "Game of" lautet, könnte das erste Ergebnis "Crazy Game of..." und das zweite "Game of Thrones" sein.

Im Wesentlichen möchte ich suchen mit icontains sondern bestellen nach startswith . Irgendwelche Ideen?

6voto

HuntedCodes Punkte 1130

Django hat neue Funktionen hinzugefügt, seit diese Frage gestellt wurde, und behandelt diesen Anwendungsfall jetzt nativ.

Sie können die Ergebnisse nach einem beliebigen Vergleich ordnen, indem Sie die folgenden Funktionen in Djangos QuerySet API verwenden:

  1. Q() Objekt : kapselt einen wiederverwendbaren Abfrageausdruck. Unser Ausdruck vergleicht das Feld des Objekts mit unserem " Spiel der Suchwert".
  2. ExressionWrapper() : umhüllt einen Abfrageausdruck, um die ModelField Typ mit output_field . In diesem Fall ist der Typ ein Boolescher Wert.
  3. annotate() : dynamisches Hinzufügen einer ModelField zu jedem QuerySet-Objekt, basierend auf dem Ergebnis eines Abfrageausdrucks. Wir wollen eine True / False Feld für die Sortierung.
  4. order_by() : Sortieren der QuerySet-Objekte nach bestimmten Feldern. Wir wollen nach dem Wert des kommentierten Feldes ordnen, in umgekehrter Reihenfolge, so dass True Werte werden zuerst angezeigt.

    from django.db.model import Q, ExpressionWrapper, BooleanField
    
    ....
    
    # Your original setup.
    search_term = 'Game of'
    data = MyModel.objects.filter(name__icontains=search_term)
    
    # Encapsulate the comparison expression.
    expression = Q(name__startswith=search_term)
    
    # Wrap the expression to specify the field type.
    is_match = ExpressionWrapper(expression, output_field=BooleanField())
    
    # Annotate each object with the comparison.
    data = data.annotate(my_field=is_match)
    
    # Order by the annotated field in reverse, so `True` is first (0 < 1).
    data = data.order_by('-my_field')
    
    ....

3voto

Chris Forrette Punkte 3174

Die von Ihnen beschriebene Reihenfolge ist subjektiv, und es gibt keine derartigen Daten in der Datenbank (soweit ich weiß). Wenn eine Funktion wie diese wichtig ist, sollten Sie sich vielleicht eine Suchmaschine wie Solr o Sphinx wo Sie konfigurieren können, wie die Relevanzwerte ermittelt werden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X