2017-10-27 6 views
0

Ich versuche, ein Suchmodul zu schreiben, das NEST verwendet und die Suchfunktion in seinem eigenen beschränkten Kontext hält.NEST Sortieren nach Textfeld

Um dies zu erreichen, habe ich die folgende Benutzerprofilsuche:

public class UserProfileSearch : IUserProfileSearch 
{ 
    ... 

    public async Task<PagedItems<UserProfileModel>> FindAsync(string searchTerm, int skip, int take) 
    { 
     var client = _elasticClientProvider.GetClient(); 
     var response = await client.SearchAsync<ElasticUserProfileModel>(s => s 
      .Index(_elasticConfiguration.GetIndex()) 
      .From(skip).Size(take) 
      .Query(q => q.MultiMatch(m => m.Fields(f => f 
       .Field(u => u.Email) 
       .Field(u => u.FirstName) 
       .Field(u => u.LastName)) 
       .Query(searchTerm))) 
      .Sort(q => q.Ascending(u => u.Email))); 
     var count = await client.CountAsync<ElasticUserProfileModel>(s => s.Index(_elasticConfiguration.GetIndex())); 
     return new PagedItems<UserProfileModel> { Items = response.Documents.Cast<UserProfileModel>().ToArray(), Total = count.Count }; 
    } 
} 

Die Reaktion versagt konsequent mit diesem Bericht:

{ "Fehler": { "Wurzel_Ursache": [{ "type": "illegal_argument_exception", "reason": Felddaten ist standardmäßig in Textfeldern deaktiviert. Setzen Sie fielddata = true auf [email] , um Felddaten in den Speicher zu laden, indem Sie den invertierten Index invertieren Verwenden Sie jedoch signifikanten SpeicherAlternativ verwenden Sie stattdessen ein Schlüsselwortfeld . "}]," Type ":" search_phase_execution_exception "," reason ":" alle shards fehlgeschlagen "," phase ":" query "," gruppiert ": true," failed_shards " : [{"shard": 0, "index": "xxxx", "node": "xxxx", "Grund": {"type": "illegal_argument_exception", "Grund": "Felddaten ist in Textfeldern deaktiviert standardmäßig. Setzen Sie fielddata = true auf [email] , um Felddaten in den Speicher zu laden, indem Sie den invertierten Index invertieren. Beachten Sie, dass dies jedoch erheblichen Speicherbedarf haben kann. Alternativ ein Keyword Feld stattdessen "}}]}," status ". 400}

aber ich habe getan, was in dem Bericht empfohlen wurde, aber der gleiche Fehler passiert hält Ich habe

definiert.
public class ElasticUserProfileModel : UserProfileModel 
{ 
    [Text(Fielddata = true)] public override string Email { get => base.Email; set => base.Email = value; } 
} 

was sollte genau das sein, was der Bericht ist zu fragen. ich mit den ElasticUserProfileModel während jeden End-to-End-Tests den Index am Wiederaufbau.

ich habe auch versucht, eher das Keyword Attribut als das Text Attribut , aber t Hat erzeugt genau den gleichen Fehler. Wenn ich nach Id (das ist numerisch) statt Email sortiere, gibt es keinen Fehler. Aber das ist eine wesentlich weniger nützliche Suche.

Gibt es eine einfache Möglichkeit, dies zu beheben?

+0

Wie sieht das Mapping aus? Erkennt das Mapping das Attribut für die überschriebene Eigenschaft wie erwartet? –

+0

@RussCam - ja ist es. Der Deskriptor zeigt die E-Mail-Eigenschaft als FieldData auf True festgelegt. –

Antwort

0

Basierend auf der Dokumentation unter https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/multi-fields.html entdeckte ich, dass eine POCO-Zeichenfolge automatisch auf ein Schlüsselwort und ein Textfeld zugeordnet wird. Die Erweiterungsmethode Suffix() war alles, was ich brauchte, um die String-Sortierung zu aktivieren.

I löschte die ElasticUserProfileModel abgeleiteten Klasse, und das Verfahren wurde FindAsync()

public async Task<PagedItems<UserProfileModel>> FindAsync(string searchTerm, int skip, int take) 
{ 
    var client = _elasticClientProvider.GetClient(); 
    var response = await client.SearchAsync<UserProfileModel>(s => s 
     .Index(_elasticConfiguration.GetIndex()) 
     .From(skip).Size(take) 
     .Query(q => q.MultiMatch(m => m.Fields(f => f 
      .Field(u => u.Email) 
      .Field(u => u.FirstName) 
      .Field(u => u.LastName)) 
      .Query(searchTerm))) 
     .Sort(q => q.Ascending(u => u.Email.Suffix("keyword")))); 
    var count = await client.CountAsync<UserProfileModel>(s => s.Index(_elasticConfiguration.GetIndex())); 
    return new PagedItems<UserProfileModel> { Items = response.Documents.ToArray(), Total = count.Count }; 
} 

, das das Problem gelöst.