2016-07-31 20 views
0

Also, das ist meine Frage:Anwenden verschiedene Filter nach Hauptmultimatch Abfrage in Elasticsearch NEST

_elasticClient.Search<SearchItem>(x => 
       x.Sort(sort).Size(itemsPerPage) 
       .Query(q => 
        q.MultiMatch(m => m 
        .Fields(fs => fs 
         .Field(p => p.Field1) 
         .Field(p => p.Field2) 
         .Field(p => p.Field3) 
         .Field(p => p.Field4) 
         .Field(p => p.Field5) 
         .Field(p => p.Field6)        
        ) 
        .Operator(Operator.And) 
        .Query(pattern) 
       ))); 

ich verschiedene Filter anwenden muß. Bereichsfilter (für den Preis), Filter Ergebnismenge wo Feld1 = "Audi" und Feld2 = "Verkauf Auto". Ich habe versucht, so etwas zu tun:

.Query(q => 
        q.MultiMatch(m => m 
        .Fields(fs => fs 
         Field(p => p.Field1) 
          .Field(p => p.Field2) 
          .Field(p => p.Field3) 
          .Field(p => p.Field4) 
          .Field(p => p.Field5) 
          .Field(p => p.Field6) 
        ) 
        .Operator(Operator.And) 
        .Query(pattern))) 
.Query(q=>q.Range(ra=>ra.Field(ff=>ff.SalePrice).GreaterThan(1000)))); 

Aber das funktioniert nicht. Ich habe alle Ergebnisse aus dem Index mit Preis größer als 1000, aber nur Suchergebnisse gesucht. Könnte mir jemand helfen?

+2

eine 'bool' Abfrage verwenden sowohl die' multi_match' und die 'range' Abfrage zu kombinieren - https://www.elastic.co/guide/en/elasticsearch/client/ net-api/2.x/bool-Abfragen.html –

Antwort

1

Sie können use a bool query to combine queries und NEST macht dies etwas einfacher zu handhaben durch die Betreiber Überlastung QueryContainer s (der Root-Abfragetyp) zu kombinieren. Hier ist ein Beispiel für NEST 2.x

void Main() 
{ 
    var connectionPool = new SingleNodeConnectionPool(new Uri("http://localhost:9200")); 
    var settings = new ConnectionSettings(connectionPool); 

    var client = new ElasticClient(settings); 

    var itemsPerPage = 20; 
    var pattern = "match query"; 

    client.Search<SearchItem>(x => x 
     .Sort(so => so 
      .Descending("_score") 
     ) 
     .Size(itemsPerPage) 
     .Query(q => q 
      .MultiMatch(m => m 
       .Fields(fs => fs 
        .Field(p => p.Field1) 
        .Field(p => p.Field2) 
        .Field(p => p.Field3) 
        .Field(p => p.Field4) 
        .Field(p => p.Field5) 
        .Field(p => p.Field6) 
       ) 
       .Operator(Operator.And) 
       .Query(pattern) 
      ) && q 
      .Range(ra => ra 
       .Field(ff=>ff.SalePrice) 
       .GreaterThan(1000) 
      ) 
     ) 
    ); 
} 

public class SearchItem 
{ 
    public int SalePrice { get; set; } 

    public string Field1 { get; set; } 

    public string Field2 { get; set; } 

    public string Field3 { get; set; } 

    public string Field4 { get; set; } 

    public string Field5 { get; set; } 

    public string Field6 { get; set; } 
} 

die

{ 
    "size": 20, 
    "sort": [ 
    { 
     "_score": { 
     "order": "desc" 
     } 
    } 
    ], 
    "query": { 
    "bool": { 
     "must": [ 
     { 
      "multi_match": { 
      "query": "match query", 
      "operator": "and", 
      "fields": [ 
       "field1", 
       "field2", 
       "field3", 
       "field4", 
       "field5", 
       "field6" 
      ] 
      } 
     }, 
     { 
      "range": { 
      "salePrice": { 
       "gt": 1000.0 
      } 
      } 
     } 
     ] 
    } 
    } 
} 

Dies finden Dokumente ergibt, dass eine Übereinstimmung für die Abfrage multi_match sind und haben auch eine salePrice größer als 1000. Da wir don Für die Bereichsabfrage muss keine Punktzahl berechnet werden (ein Dokument verfügt entweder über eine salePrice, die größer als 1000 ist oder nicht). Die Bereichsabfrage kann in einem Filterkontext ausgeführt werden. Eine etwas verfeinerte Version

client.Search<SearchItem>(x => x 
    .Sort(so => so 
     .Descending("_score") 
    ) 
    .Size(itemsPerPage) 
    .Query(q => q 
     .MultiMatch(m => m 
      .Fields(fs => fs 
       .Field(p => p.Field1) 
       .Field(p => p.Field2) 
       .Field(p => p.Field3) 
       .Field(p => p.Field4) 
       .Field(p => p.Field5) 
       .Field(p => p.Field6) 
      ) 
      .Operator(Operator.And) 
      .Query(pattern) 
     ) && +q 
     .Range(ra => ra 
      .Field(ff=>ff.SalePrice) 
      .GreaterThan(1000) 
     ) 
    ) 
); 

den einstelligen + Operator an die Bereichsabfrage anhängt ist eine Abkürzung für einen Bool Abfragefilter. Die Abfrage json sieht nun wie

{ 
    "size": 20, 
    "sort": [ 
    { 
     "_score": { 
     "order": "desc" 
     } 
    } 
    ], 
    "query": { 
    "bool": { 
     "must": [ 
     { 
      "multi_match": { 
      "query": "match query", 
      "operator": "and", 
      "fields": [ 
       "field1", 
       "field2", 
       "field3", 
       "field4", 
       "field5", 
       "field6" 
      ] 
      } 
     } 
     ], 
     "filter": [ 
     { 
      "range": { 
      "salePrice": { 
       "gt": 1000.0 
      } 
      } 
     } 
     ] 
    } 
    } 
}