Elasticsearch Nest-Platzhalterabfrage mit Leerzeichen

Kurze Version:

Ich möchte eine elastische Suchanfrage mit Nest schreiben, um die vollständigen indizierten Elemente zu erhalten ContentIndexables in meinem Fall als mein benutzerdefinierter Typ), die indiziert wurden. Die Abfrage unterliegt einem Begriff query of [some string] + * (d. H. String.StartsWith (), wobei [some string] Leerzeichen enthalten kann oder nicht.

Dies ist anders alsCompletionSuggester da ich das vollständige Objekt abrufen muss und keine Vorschläge für Zeichenfolgen.

as ich bisher ausprobiert habe:

Wenn ich nach einem Text ohne Leerzeichen frage, wird die gewünschte Ausgabe mit dem folgenden Code zurückgegeben. Wenn mein Suchbegriff jedoch Leerzeichen enthält, werden die erwarteten Ergebnisse nicht zurückgegeben.

So durchsuche ich die Felder:

var searchResults = _client.Search<ContentIndexable>(
            body =>
            body
                .Index(indexName)
                .Query(
                    query =>
                    query.QueryString(
                        qs => qs.
                                  OnFields(f => f.Title, f => f.TextContent)
                                  .Query(searchTerm + "*"))));

Und dies ist ein Komponententest, der zeigt, wie das Problem reproduziert werden kann:

indexService.IndexUserItemsSync(testGuid, IndexType.submission, new ContentIndexable
        {
            ContentId = Guid.NewGuid(),
            TextContent = "Some description",
            Title = "title"
        });

        indexService.IndexUserItemsSync(testGuid, IndexType.submission, new ContentIndexable
        {
            ContentId = Guid.NewGuid(),
            TextContent = "Some description",
            Title = "title that is long"
        });

        indexService.IndexUserItemsSync(testGuid, IndexType.submission, new ContentIndexable
        {
            ContentId = Guid.NewGuid(),
            TextContent = "Some description",
            Title = "title that likes"
        });

        indexService.IndexUserItemsSync(testGuid, IndexType.submission, new ContentIndexable
        {
            ContentId = Guid.NewGuid(),
            TextContent = "Some description",
            Title = "titlethat"
        });

        var searchResult = indexService.SearchUserItems(testGuid, IndexType.submission, 10, "title");
        Assert.IsNotNull(searchResult);
// this one works
        Assert.AreEqual(4, searchResult.Count());

        var searchResult2 = indexService.SearchUserItems(testGuid, IndexType.submission, 10, "title that");
        Assert.IsNotNull(searchResult2);
// this one does not!!! searchREsult2.Count() evaluates to 0
        Assert.AreEqual(2, searchResult2.Count());

Wie Sie sehen, wird bei der Eingabe von "title that" die Suche anstelle der beiden erwarteten Zeilen leer zurückgegeben.

Aktualisieren Weitere Informationen: Ich erstelle einen Index für meinen Typ ContentIndexable:

public class ContentIndexable : IIndexable
{
    public Guid ContentId { get; set; }
    public string Title { get; set; }
    public string TextContent { get; set; }
}

Mit diesem Code:

_client.CreateIndex(
    indexName,
    descriptor =>
    descriptor.AddMapping<ContentIndexable>(
        m => m.Properties(
            p => p.Completion(s => s
                                       .Name(n => n.Title)
                                       .IndexAnalyzer("standard")
                                       .SearchAnalyzer("standard")
                                       .MaxInputLength(30)
                                       .Payloads()
                                       .PreserveSeparators()
                                       .PreservePositionIncrements())
                     .Completion(s => s.Name(n => n.TextContent)
                                          .IndexAnalyzer("standard")
                                          .SearchAnalyzer("standard")
                                          .MaxInputLength(50)
                                          .Payloads()
                                          .PreserveSeparators()
                                          .PreservePositionIncrements())
                 )));

Ich habe sogar versucht, das Leerzeichen sowohl beim Indexieren als auch beim Abfragen mit @ zu umgehestring.Replace(" ", @"\ ") aber das hat nicht geholfen.

Das Ändern des Suchtyps auf Platzhalter hat auch nicht geholfen:

var searchResults = _client.Search<ContentIndexable>(
            body =>
            body
                .Index(indexName)
                .Query(
                    query => query.Wildcard(qd => qd.OnField(f => f.Title).Value(searchTerm + "*"))));

Weiß jemand, was ich falsch mache?

Bitte beachten Sie, dass meinCompletionSuggester version arbeitet mit Leerzeichen, gibt aber leider nur Strings zurück. Ich muss das @ bekommcomplete item out um das @ abzurufContentId. Implementierung von MY CompletionSuggester:

public IEnumerable<string> GetAutoCompleteSuggestions(Guid userId, IndexType indexType, int size, string searchTerm)
    {
        string indexName = getIndexName(indexType, userId);

        var result = _client.Search<ContentIndexable>(
            body => body.Index(indexName)
                        .SuggestCompletion("content-suggest" + Guid.NewGuid(),
                                           descriptor => descriptor
                                                             .OnField(t => t.Title)
                                                             .Text(searchTerm)
                                                             .Size(size)));

        if (result.Suggest == null)
        {
            return new List<string>();
        }

        return (from suggest in result.Suggest
                from value in suggest.Value
                from options in value.Options
                select options.Text).Take(size);
    }

Ich weiß, ich kann die Vorschläge annehmen, den vollständigen Wert herausholen (was zu den beiden erwarteten Elementen führt) und dann mit meiner ersten Methode eine vollständige Übereinstimmung herstellen, wobei jedoch zwei separate Aufrufe in ElasticSearch erforderlich sind (einer für die vollständige) vorschlag und der zweite für den begriff abfrage) aber idealerweise würde ich es wenn möglich auch ohne rundreise machen.

Vielen Dank im Voraus

Antworten auf die Frage(2)

Ihre Antwort auf die Frage