2014-12-16 21 views
6

Ho un catalogo di prodotti su cui voglio calcolare gli aggregati. Questo è abbastanza semplice per le proprietà di livello superiore come marca, produttore, ecc. Il problema deriva dal tentativo di calcolare i conteggi di gamma sui prezzi perché vendiamo in più valute, e quando si determinano questi conteggi voglio solo interrogare su una valuta ad un tempo. Ecco un esempio della mia mappatura oggetto prodotto:Aggregati in Nest (ElasticSearch) su oggetti child/nested

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

Ecco un esempio di una query per tutti i prodotti con un prezzo inferiore a 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)))); 

La richiesta elasticsearch che questo genera è:

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

Questo restituisce tutti i prodotti con almeno un prezzo inferiore a 100 in qualsiasi valuta, come previsto. Quello che non sono stato in grado di fare è di eseguire questa query solo sui prezzi in una data valuta. Ad esempio, l'aggiunta di questo filtro alla query rimuove solo i prodotti che non hanno un prezzo in moneta 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)))); 

Ho provato il trattamento della lista prezzi sia come oggetto nidificato e un oggetto figlio, ma elasticsearch non sembra che indicizzi i prezzi in questo modo perché ottengo un errore di "AggregationExecutionException [[nested] percorso nidificato [prezzi] non è nidificato]" e simile per le query HasChild. È possibile generare query e aggregati in questo modo?

+0

controllo questo post [Come posso utilizzare tipi nidificati con il cliente NEST per Elastic Ricerca ] (http://stackoverflow.com/questions/17834767/how-can-i-use-nested-types-with-nest-client-for-elastic-search). Potrebbe aiutare – octavioccl

+0

Sfortunatamente quella risposta sembra non essere aggiornata. Come notato nella risposta più recente, il metodo fluente NestedObject non sembra funzionare più e ho provato a decorare la proprietà Prices con l'attributo [ElasticProperty (Type = FieldType.Nested)] ma i prezzi non vengono ancora indicizzati come un oggetto nidificato Se sono in grado di ottenere la mappatura verso il basso, trattare i prezzi come un oggetto nidificato mi consente di calcolare gli aggregati come descritto sopra? –

risposta

3

In primo luogo è necessario mappare il tipo nidificato:

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

Dopo di che, provare a eseguire questa query:

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

Questo ottiene tutti i criteri che sto cercando nella query, ma sta ancora recuperando i risultati con un prezzo <100 in qualsiasi valuta. Penso che mi stia imbattendo nel problema descritto qui [link] (http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/mapping-nested-type.html) Penso che la tua prima risposta era sulla strada giusta, ho bisogno di mappare i prezzi come un tipo annidato. Crea una nuova risposta dicendo questo e io lo segnerò. –

Problemi correlati