2017-08-22 7 views
0

Ich lerne ElasticSearch und benutze NEST. Ich habe ein Objekt und möchte mehrere Felder indizieren und dann nach Kombinationen dieser Felder suchen. Wenn ich suche, erhalte ich Ergebnisse, die nicht mit meinen Suchbegriffen übereinstimmen. Unten ist der Code zum Indizieren der Daten.ElasticSearch NEST Indizierung und Suche in mehreren Feldern

client.CreateIndex(CurrentIndexName, i => i 
    .Settings(s => s 
     .NumberOfShards(2) 
     .NumberOfReplicas(0) 
     .Analysis(analysis => analysis 
     .Analyzers(analyzer => analyzer 
      .Custom("substring_analyzer", analyzerDescripter => analyzerDescripter 
      .Tokenizer("tokenizer") 
      .Filters("lowercase") 
     ) 
     ) 
     .Tokenizers(tk => tk 
      .EdgeNGram("tokenizer", tokenizer => tokenizer 
      .MaxGram(10) 
      .MinGram(2) 
      .TokenChars(new List<TokenChar> { TokenChar.Letter, TokenChar.Digit }) 
     ) 
     ) 
    ) 
    ) 
    .Mappings(m => m 
     .Map<CostCenter>(map => map 
     .AutoMap() 
     .Properties(ps => ps 
      .Text(s => s 
      .Name(n => n.CC_Acct_1) 
      .Analyzer("substring_analyzer") 
     ) 
      .Text(s => s 
      .Name(n => n.CC_Acct_2) 
      .Analyzer("substring_analyzer") 
     ) 
      .Text(s => s 
      .Name(n => n.CC_Acct_3) 
      .Analyzer("substring_analyzer") 
     ) 
     ) 
    ) 
    ) 
); 

Hier ist mein Suchcode.

 var searchResult = client.Search<CostCenter>(s => s 
    .Size(1000) 
    .Query(q => q 
     .Match(m => m 
     .Field(f => f.CC_Acct_1) 
     .Query("0061") 
    ) && 
     q.Match(m => m 
     .Field(f => f.CC_Acct_2) 
     .Query("9061") 
    ) 
    ) 
); 

Damit erhalte ich Ergebnisse, die nicht entweder Zeichenfolge übereinstimmen (d CC_Acct_1 = "0056" und CC_Acct_2 = "9056"). Wenn ich die zweite Übereinstimmungserklärung entferne, scheint alles zu funktionieren. Ist es möglich zu tun, was ich zu erreichen versuche?

AKTUALISIERUNG: Unten finden Sie ein Beispiel für die Daten, die ich indexiere.

[{ 
    "Cost_Center": "0056-5711-05910000", 
    "CC_Acct_1": "0056", 
    "CC_Acct_2": "5711", 
    "CC_Acct_3": "5910000", 
    }, 
{ 
    "Cost_Center": "0061-9061-05910000", 
    "CC_Acct_1": "0061", 
    "CC_Acct_2": "9061", 
    "CC_Acct_3": "6790000", 

}, 
{ 
    "Cost_Center": "0061-9061-05910000", 
    "CC_Acct_1": "0061", 
    "CC_Acct_2": "9061", 
    "CC_Acct_3": "5910000", 
}, 
{ 
    "Cost_Center": "0056-5711-05910000", 
    "CC_Acct_1": "0056", 
    "CC_Acct_2": "5711", 
    "CC_Acct_3": "6790000", 
    }, 
{ 
    "Cost_Center": "0061-5711-05910000", 
    "CC_Acct_1": "0061", 
    "CC_Acct_2": "5711", 
    "CC_Acct_3": "6790000",  
}, 
{ 
    "Cost_Center": "0056-9061-05910000", 
    "CC_Acct_1": "0056", 
    "CC_Acct_2": "9061", 
    "CC_Acct_3": "5910000", 
}, 
{ 
    "Cost_Center": "0056-9061-05910000", 
    "CC_Acct_1": "0056", 
    "CC_Acct_2": "9061", 
    "CC_Acct_3": "5910000", 
    }, 
{ 
    "Cost_Center": "0056-5711-05910000", 
    "CC_Acct_1": "0056", 
    "CC_Acct_2": "5711", 
    "CC_Acct_3": "5910000", 
}, 
{ 
    "Cost_Center": "0056-5711-05910000", 
    "CC_Acct_1": "0056", 
    "CC_Acct_2": "5711", 
    "CC_Acct_3": "5910000", 
    }, 
{ 
    "Cost_Center": "0056-5711-05910000", 
    "CC_Acct_1": "0056", 
    "CC_Acct_2": "5711", 
    "CC_Acct_3": "5910000", 
} 
] 

Ich habe weitere Forschung getan, und es sieht aus wie die Elemente, die an der Spitze meiner Rückkehr Satz (das heißt höhere Punktzahl) sind übereinstimmen. Ich möchte, dass das zurückgegebene Ergebnis nur solche enthält, die exakt übereinstimmen. Zum Beispiel nur Elemente, bei denen CC_Acct_1 "0061" und CC_Act_2 "9061" ist oder wenn ich "90" in meinen zweiten Suchfeldelementen hatte, wo CC_Act_2 "90" enthält. In diesem Fall wären beide Elemente, bei denen CC_Act_2 "9061" oder "1090" ist, enthalten.

+1

Es ist möglich. Wären Sie in der Lage, Ihre Frage zu aktualisieren, um einige Daten zu indizieren und einzuschließen, was Sie für die angegebene Abfrage erwarten würden? –

+0

Ich versuche, eine Typ-Ahead zu tun, so wie der Benutzer anfängt zu tippen mögliche Werte angezeigt werden. – James

+0

Für die Art voraus, schauen Sie sich die Fertigstellung suggester: https://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters-completion.html. Je nachdem, wie Sie die Typ-Ahead-Suche bereitstellen möchten, könnte dies Ihren Anforderungen entsprechen. Wenn Sie komplexere Analysen durchführen müssen, dann ist es möglicherweise nicht geeignet, aber aus den Informationen, die Sie zur Verfügung gestellt haben, sieht es aus, als ob es eine gute Passform –

Antwort

0

Ich habe einige Fortschritte gemacht, bin mir aber nicht sicher, ob das der beste Weg ist. Zuerst änderte ich meine Abfrage wie folgt.

var searchResult = client.Search<CostCenter>(s => s 
    .Size(1000) 
    .Index("test") 
    .Query(q => q) 
     .MatchPhrase(m => m 
     .Field(f => f.CC_Acct_1) 
     .Query("0056") 
    ) && 
     q.MatchPhrase(m => m 
     .Field(f => f.CC_Acct_2) 
     .Query("9056") 
    ) 
    ) 
); 

Dies ergab die gewünschten Ergebnisse, aber wenn ich die Abfrage für das dritte Feld zurückgegeben wurden keine Ergebnisse gegeben.

var searchResult = client.Search<CostCenter>(s => s 
    .Size(1000) 
    .Index("test") 
    .Query(q => q 
     .MatchPhrase(m => m 
     .Field(f => f.CC_Acct_1) 
     .Query("0056") 
    ) && 
     q.MatchPhrase(m => m 
     .Field(f => f.CC_Acct_2) 
     .Query("9056") 
    ) && 
     q.MatchPhrase(m => m 
     .Field(f => f.CC_Acct_3) 
     .Query("679") 
    ) 
    ) 
); 

Ich wechselte dann zu den folgenden und erhielt die gewünschten Ergebnisse.

var searchResult = client.Search<CostCenter>(s => s 
    .Size(1000) 
    .Index("test") 
    .Query(q => q 
     .Bool(b => b 
     .Must(bs => bs.Term(p => p.CC_Acct_1, "0056"), 
      bs => bs.Term(p => p.CC_Acct_2, "9056"), 
      bs => bs.Term(p => p.CC_Acct_3, "679") 
     )   
    ) 
    ) 
); 

kann ich eine der Lambda-Funktionen entfernen und nur die Elemente, die dem entsprechen, was ich suche. Lassen Sie mich wissen, ob es einen besseren und effizienteren Weg gibt, dies zu erreichen.

+0

Angesichts der Beispieldaten sehe ich nicht, wie die zweite und dritte Abfragen hier würden Übereinstimmungen zurückgeben - es gibt keine Elemente in der Beispielsammlung, die '" 679 "' als Teil von 'CC_Acct_3' enthalten, was eine Voraussetzung ist, um die Abfrage zu erfüllen. –

+0

Entschuldigung. Die oben aufgeführten Daten sind eine Teilprobe des Datensatzes. Was ich ursprünglich oben gepostet habe, ist der tatsächliche Code, den ich hatte und ich habe nicht überprüft, ob der letzte Begriff übereinstimmt. Ich werde es aktualisieren, um übereinstimmende Daten zu haben. – James

Verwandte Themen