2017-09-04 1 views
1

J'ai une structure de produits qui sont disponibles dans différents magasins avec des prix différents:groupe ElasticSearch et l'ordre par min valeur du champ imbriqué

[{ 
    "name": "SomeProduct", 
    "store_prices": [ 
    { 
     "store": "FooStore1", 
     "price": 123.45 
    }, 
    { 
     "store": "FooStore2", 
     "price": 345.67 
    } 
    ] 
},{ 
    "name": "OtherProduct", 
    "store_prices": [ 
    { 
     "store": "FooStore1", 
     "price": 456.78 
    }, 
    { 
     "store": "FooStore2", 
     "price": 234.56 
    } 
    ] 
}] 

Je veux montrer une liste de produits, commandés par le plus bas prix croissant, limité à 10 résultats, de cette façon:

  • SomeProduct: 123,45 USD
  • OtherProduct: 234,56 USD

Comment faire? J'ai essayé l'approche d'agrégation imbriquée décrit dans https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-nested-aggregation.html mais il retourne seulement le prix min de tous les produits, et non le prix min respectif pour chaque produit:

{ 
    "_source": [ 
    "name", 
    "store_prices.price" 
    ], 
    "query": { 
    "match_all": {} 
    }, 
    "sort": { 
    "store_prices.price": "asc" 
    }, 
    "aggs": { 
    "stores": { 
     "nested": { 
     "path": "store_prices" 
     }, 
     "aggs": { 
     "min_price": {"min": {"field": "store_prices.price"}} 
     } 
    } 
    }, 
    "from": 0, 
    "size": 10 
} 

Dans SQL, ce que je veux faire pourrait être décrit à l'aide la requête suivante. Je crains que je pense trop « dans sql »:

SELECT 
    p.name, 
    MIN(s.price) AS price 
FROM 
    products p 
INNER JOIN 
    store_prices s ON s.product_id = p.id 
GROUP BY 
    p.id 
ORDER BY 
    price ASC 
LIMIT 10 
+0

Pouvez-vous montrer la requête que vous avez essayé jusqu'à présent? – Val

+0

@Val: mise à jour dans la question; Fondamentalement, l'exemple de requête à partir des docs. –

Répondre

1

Vous avez besoin d'un nested sorting:

{ 
    "query": // HERE YOUR QUERY, 
    "sort": { 
    "store_prices.price": { 
     "order" : "asc", 
     "nested_path" : "store_prices", 
     "nested_filter": { 
      // HERE THE FILTERS WHICH ARE EVENTUALLY 
      // FILTERING OUT SOME OF YOUR STORES 
     } 
    } 
    } 
} 

Faites attention que vous devez répéter les requêtes éventuelles imbriquées à l'intérieur du champ de filtre imbriqué . Vous trouvez alors le prix dans le champ score de la réponse.