2017-04-25 4 views
1

Ich habe eine List eines Objekts und ich muss eine Abfrage in Morphia führen, um das eindeutige Ergebnis von einer anderen Einbettung List von String in bestimmten Objekt zu erhalten.Wie man Aggregation in Morphium durchführt?

Objektklasse:

@Entity 
public class Fruits { 
    @NotNull private Long id; 
    @NotNull private List<String> categories; 
} 

Daten im JSON-Format:

Früchte:

{[ 
    "id": 1234566, 
    "categories": ["A", "B", "C", "D"] 
], 
[ 
    "id": 32434, 
    "categories": ["A", "C", "E", "F"] 
], 
[ 
    "id": 32434, 
    "categories": ["A", "L", "M", "N"] 
] 
} 

Das Ergebnis der Aggregation sein soll:

[A,C,B,D,E,F,L,M,N] 

Der Ausgang ist in sortierter Form. Wie kann ich dies in Morphium erreichen? Ich habe versucht, nach offizieller Dokumentation zu suchen, konnte aber den Hinweis nicht finden.

Jede Hilfe oder Hinweis wäre nennenswert. Dank

EDIT-1

List<Fruits> fruitList = fruitControllerDao.search(fruitList); 

List<Category> categories = new ArrayList<>(); 
datastore.createAggregation(Fruits.class) 
     .unwind("categories") 
     .group(Group.id(Group.grouping("categories"))) 
     .sort(Sort.ascending("_id.categories")) 
     .project(Projection.projection("_id").suppress(), 
      Projection.projection("categories", "_id.categories")) 

     .aggregate(Category.class).forEachRemaining(categories::add); 

und ich

class Category { 
    private String category; 
} 

Daten in fruitList geschaffen haben, ist unbrauchbar und ich brauche aggregation auf der fruitList (Kasse der JSON-Format) selbst zu übernehmen.

Antwort

1

Sie können den folgenden Code verwenden, um eindeutige & Sortierkategorien mit Aggregationspipeline zu erhalten.

Bereiten Abfrage Filter:

Query<Fruits> query = datastore.createQuery(Fruits.class); 
Iterator<Fruits> fruitIterator = fruitList .iterator(); 
CriteriaContainer orQuery = query.or(); 
while(fruitIterator.hasNext()) { 
     Fruits fruit = fruitIterator.next(); 
     orQuery.add(query.and(query.criteria("id").equal(fruit.getId()), query.criteria("categories").equal(fruit.getCategories()))); 
} 

die unten angegebene Abfrage $matches auf Abfragefilter und die $unwinds gefolgt von categories$group die Duplikate zu entfernen und zu sortieren. Der letzte Schritt ist das Lesen des Wertes aus der Gruppierungsstufe und in das Kategoriefeld.

List<Category> categories = new ArrayList<>(); 
    datastore.createAggregation(Fruits.class) 
     .match(query) 
     .unwind("categories") 
     .group(Group.id(Group.grouping("categories"))) 
     .sort(Sort.ascending("_id.categories")) 
     .project(Projection.projection("_id").suppress(), Projection.projection("category", "_id.categories")) 
     .aggregate(Category.class).forEachRemaining(categories::add); 


class Category { 
    private String category; 
} 

Update:

Mongo Shell Abfrage

[{ "$match" : { "$or" : [ { "$and" : [ { "_id" : 1234566} , { "categories" : [ "A" , "B" , "C" , "D"]}]} , { "$and" : [ { "_id" : 32434} , { "categories" : [ "A" , "C" , "E" , "F"]}]} , { "$and" : [ { "_id" : 32434} , { "categories" : [ "A" , "L" , "M" , "N"]}]}]}}, { "$unwind" : "$categories"}, { "$group" : { "_id" : { "categories" : "$categories"}}}, { "$sort" : { "_id.categories" : 1}}, { "$project" : { "_id" : 0 , "category" : "$_id.categories"}}] 
+0

Vielen Dank für Ihre Antwort. '_id' bezieht sich auf' Fruits.id' hier. Recht? –

+0

Gern geschehen. Nein, es ist die '_id' aus' group'. Mongo-Shell-Abfrage zum Vergleich hinzugefügt und auch einige Erklärungen in den Post hinzugefügt. – Veeram

+0

Ich versuche diesen Code zu implementieren, bin aber verwirrt darüber, wo und wie Sie die 'Fruit'-Objektdaten im obigen Code verwenden. Könnten Sie mir bitte hier helfen? Ich meine Wie kann ich diese Aggregationsabfrage auf über Json anwenden? –

Verwandte Themen