2014-12-16 12 views
6

Mam katalog produktów, na których chcę obliczyć dane zagregowane. Jest to wystarczająco proste w przypadku właściwości najwyższego poziomu, takich jak nazwa marki, producent itp. Problem polega na próbie obliczenia liczby wyświetleń na cenach, ponieważ sprzedajemy je w wielu walutach, a przy ustalaniu tych liczb chcę zapytać tylko o jedną walutę. czas. Oto przykład z mojego obiektu produkt mapowania:Agregacje w gnieździe (ElasticSearch) na obiektach potomnych/zagnieżdżonych

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; } 
} 

Oto przykład zapytania dla wszystkich produktów z ceną poniżej 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)))); 

Żądanie ElasticSearch, że generuje to:

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

Sprowadza wszystkie produkty, których cena jest niższa niż 100 w dowolnej walucie, jak można się spodziewać. To, czego nie mogłem zrobić, to uruchomić zapytanie dotyczące tylko cen w danej walucie. Na przykład, dodając ten filtr do zapytania usuwa tylko produkty, które nie mają ceny w walucie 1:

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)))); 

próbowałem leczenia listę ceny zarówno jako zagnieżdżonego obiektu i obiektu podrzędnego, ale ElasticSearch nie wydaje się indeksować ceny w ten sposób, ponieważ pojawia się błąd "AggregationExecutionException [[zagnieżdżone] zagnieżdżone ścieżki [ceny] nie jest zagnieżdżony]" i podobne dla kwerend HasChild. Czy w ten sposób można wygenerować zapytania i agregaty?

+0

wyboru ten post [Jak mogę użyć zagnieżdżone typy z klientem Nest Elastic Search ] (http://stackoverflow.com/questions/17834767/how-can-i-use-nested-types-with-nest-client-for-elastic-search). To może pomóc – octavioccl

+0

Niestety ta odpowiedź wydaje się być nieaktualna. Jak zauważono w najnowszej odpowiedzi, płynna metoda NestedObject nie działa, a ja próbowałem dekorować właściwość Ceny za pomocą atrybutu [ElasticProperty (Type = FieldType.Nested)], ale ceny nadal nie są indeksowane jako obiekt zagnieżdżony. Jeśli uda mi się mapować, czy traktowanie cen jako obiektu zagnieżdżonego pozwala mi obliczyć agregaty w sposób opisany powyżej? –

Odpowiedz

3

Najpierw trzeba odwzorować typ zagnieżdżony:

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

Po tym, spróbuj wykonać to zapytanie:

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

To dostaje wszystkie kryteria, których szukam w zapytaniu, ale wciąż pobiera wyniki o cenie <100 w dowolnej walucie. Myślę, że mam problem opisany tutaj [link] (http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/mapping-nested-type.html) Myślę, że twoja pierwsza odpowiedź był na dobrej drodze, muszę mapować ceny jako typ zagnieżdżony. Utwórz nową odpowiedź, mówiąc, że to zaznaczę. –