2014-12-16 5 views
6

Ich habe einen Katalog von Produkten, für die ich Aggregate berechnen möchte. Dies ist einfach genug für Top-Level-Eigenschaften wie Markenname, Hersteller, usw. Das Problem kommt mit dem Versuch, Bereich zählt auf Preise zu berechnen, weil wir in mehreren Währungen verkaufen, und wenn ich diese Zählungen bestimmen möchte ich nur auf eine Währung abfragen Zeit. Hier ist ein Beispiel meiner Produktes Objektzuordnung:Aggregate in Nest (ElasticSearch) für untergeordnete/verschachtelte Objekte

public class Product 
{ 
    public int ID { get; set;} 
    public string Name { get; set; } 
    public IList<Price> Prices { get; set; } 
} 

public class Price 
{ 
    public int CurrencyID { get; set; } 
    public decimal Cost { get; set; } 
} 

Hier ist ein Beispiel für eine Abfrage für alle Produkte mit einem Preis unter 100:

var cheapProducts = client.Search<Product>(s => s 
    .From(0) 
    .Size(1000) 
    .Query(q => q 
     .Range(r => r 
      .LowerOrEquals(100) 
      .OnField(f => f.Prices.FirstOrDefault().Cost)))); 

Die Elasticsearch Anfrage, dass dies erzeugt ist:

{ 
    "from": 0, 
    "size": 1000, 
    "query": { 
     "range" : { 
      "prices.cost": { 
       "lte": "100" 
      } 
     } 
    } 
} 

Dies gibt alle Produkte mit mindestens einem Preis unter 100 in jeder Währung zurück, wie Sie erwarten würden. Was ich nicht tun konnte, ist diese Abfrage nur gegen Preise in einer bestimmten Währung auszuführen. Zum Beispiel das Hinzufügen dieser Filter auf die Abfrage entfernt nur Produkte, die einen Preis in der Währung nicht 1 haben:

var cheapProducts = client.Search<Product>(s => s 
    .From(0) 
    .Size(1000) 
    .Filter(f => f 
     .Term(t => t 
      .Prices.FirstOrDefault().CurrencyID, 1)) 
    .Query(q => q 
     .Range(r => r 
      .LowerOrEquals(100) 
      .OnField(f => f.Prices.FirstOrDefault().Cost)))); 

Ich habe versucht, die Preisliste als beide Objekt eine verschachtelte Objekt und ein Kind zu behandeln, aber Elasticsearch scheint die Preise auf diese Weise nicht zu indizieren, weil ich einen Fehler von "AggregationExecutionException [[verschachtelter] verschachtelter Pfad [Preise] ist nicht verschachtelt") und ähnlich für HasChild-Abfragen erhalte. Ist es möglich, auf diese Weise Abfragen und Aggregate zu generieren?

+0

Check this post [Wie kann ich verschachtelte Typen mit NEST-Client für Elastic Suche verwenden ] (http://stackoverflow.com/questions/17834767/how-can-i-use-nested-types-with-nest-client-for-elastic-search). Es könnte helfen – octavioccl

+0

Leider scheint diese Antwort veraltet zu sein. Wie in der letzten Antwort erwähnt, scheint die flüssige NestedObject-Methode nicht mehr zu funktionieren, und ich habe versucht, die Prices-Eigenschaft mit dem Attribut [ElasticProperty (Type = FieldType.Nested)] zu dekorieren, aber Prices wird immer noch nicht indiziert ein verschachteltes Objekt Wenn es mir möglich ist, das Mapping herunter zu bekommen, würde es mir erlauben, die Preise als verschachteltes Objekt zu behandeln, wie ich oben beschrieben habe? –

Antwort

3

Zuerst müssen Sie die verschachtelte Art zur Karte:

public class Product 
{ 
    public int ID { get; set; } 
    public string Name { get; set; } 
    [ElasticProperty(Type = FieldType.Nested)] 
    public IList<Price> Prices { get; set; } 
} 

Danach versuchen Sie diese Abfrage ausführen:

var cheapProducts = client.Search<Product>(s => s 
      .From(0) 
      .Size(1000) 
      .Query(x => x.Term(p => p 
       .Prices.First().CurrencyID, 1) && x.Range(r => r 
        .LowerOrEquals(100) 
        .OnField(f => f.Prices.FirstOrDefault().Cost)))); 
+0

Das bekommt alle Kriterien, nach denen ich suche, aber es liefert immer noch Ergebnisse mit einem Preis <100 in jeder Währung. Ich denke, ich laufe auf das hier beschriebene Problem [link] (http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/mapping-nested-type.html) Ich denke, Ihre erste Antwort war auf dem richtigen Weg, ich muss die Preise als geschachtelten Typ zuordnen. Erstellen Sie eine neue Antwort, die das sagt, und ich werde es markieren. –

Verwandte Themen