2017-05-07 4 views
0

Ich versuche, Agregation mit Feder mongodb Vorlage zu verwenden. Die Gruppierung muss auf der dritten Dokumentenebene erfolgen. Eingabedokument istAgrgregation mit mongoDBtemplate für verschachteltes Dokument

{ 
    "_id": "59036b0fa036cc28c8e07db6", 
    "sections": [{ 
     "srcName": "test1", 
     "data": [{ 
       "srcKey": "", 
       "rowIdx": 0, 
       "values": [{ 
         "srcDesc": "Assets" 
        }, 
        { 
         "srcDesc": "NonAssets" 
        }, 
        { 
         "srcDesc": "liabilities" 
        } 
       ] 
      }, 
      { 
       "srcKey": "01", 
       "rowIdx": 1, 
       "values": [{ 
        "srcDesc": "NonAssets" 
       }] 
      } 
     ] 
    }] 
} 

Wesentlichen Abfrage wie

select distinct(srcdesc) from document where srcName="test1"; 

laufen Ich möchte Bitte beachten Sie, dass srcDesc dritte Ebene der Verschachtelung ist. Ich versuche unter Java-Code

private MatchOperation getMatchOPeration(String sectionName){ 
     Criteria criteira=Criteria.where("sectionName").in(sectionName); 
     return match(criteira); 
    } 

    private GroupOperation getGroupOperaion(){ 
     return group("srcDesc").last("srcDesc").as("srcDesc"); 
    } 

private ProjectionOperation getProjectionOPeration(){ 
     return project("srcDesc").and("srcDesc").previousOperation(); 
    } 

public List<SourceName> findAllSourceNamesBySection(String sectionName){ 
     List<SectionsDocument> sourceNameList=new ArrayList<>(); 
     MatchOperation matchOPeration=getMatchOPeration(sectionName); 
     GroupOperation groupOperation=getGroupOperaion(); 
     ProjectionOperation projectionOperation=getProjectionOPeration(); 
     AggregationResults<SectionsDocument> aggregationResults= 
     mongoTemplate.aggregate(Aggregation.newAggregation(
      matchOPeration, 
      unwind("sections.data.values"), 
      groupOperation, 
      projectionOperation),StatDocument.class,SectionsDocument.class); 
      sourceNameList=aggregationResults.getMappedResults(); 
     return new ArrayList<>(); 
    } 
+0

Was ist dein Mongo-Server und die Frühlings-Mongo-Version? – Veeram

+0

@veeram, ich bin mit org.springframework.boot \t \t \t Feder-boot-Starter-data-mongodb \t \t \t 1.5.1.RELEASE org.springframework.boot \t \t \t Feder-boot-Starter-data-mongodb \t \t \t 1.5.1.RELEASE Abhinav1singhal

+0

Was ist deine Mongo Server Version? – Veeram

Antwort

0

Sie können Ihren Code unten aktualisieren.

Added $unwindsections & sections.data vor sections.data.values Abwickeln zu entspannen.

Aktualisiert $group get distinct srcDesc mit $addToSet Betreiber.

Die $project Stufe entfernt.

private MatchOperation getMatchOperation(String sectionName){ 
    Criteria criteira=Criteria.where("sections.srcName").in(sectionName); 
    return match(criteira); 
} 

private GroupOperation getGroupOperaion(){ 
    return group().addToSet("sections.data.values.srcDesc").as("srcDescs"); 
} 

public List<String> findAllSrcDescBySection(String sectionName){ 
    MatchOperation matchOperation=getMatchOperation(sectionName); 
    GroupOperation groupOperation=getGroupOperaion(); 
    BasicDBObject aggregationResults= 
       mongoTemplate.aggregate(Aggregation.newAggregation(
         matchOperation, 
         unwind("sections"), 
         unwind("sections.data"), 
         unwind("sections.data.values"), 
         matchOperation, 
         groupOperation), collectionname, BasicDBObject.class).getUniqueMappedResult(); 
    return (ArrayList)aggregationResults.get("srcDescs"); 
} 

-Update 3.4 Version:

Dies ist ähnlich wie oben, aber statt $unwind'ing sind wir $reduce'ing-$projectsrcDescs aus jedem Dokument.

$map + $filter, um die sections Elemente mit dem Eingang srcName zu filtern, gefolgt von map, um die Ausgabe zu transformieren. $reduce verwendet die Ausgabe der Filterstufe innerhalb der Kartenstufe, um ($concatArrays Teil) srcDesc über alle values in jedem data zu extrahieren und zusammenzuführen.

$unwind + $group, um eindeutig srcDesc mit $addToSet Operator zu erhalten.

aggregate([{ 
     $project: { 
      srcDescs: { 
       $arrayElemAt: [{ 
        $map: { 
         input: { 
          $filter: { 
           input: "$sections", 
           as: "sectionsf", 
           cond: { 
            $eq: ["$$sectionsf.srcName", "test1"] 
           } 
          } 
         }, 
         as: "sectionsm", 
         in: { 
          $reduce: { 
           input: "$$sectionsm.data", 
           initialValue: [], 
           in: { 
            $concatArrays: ["$$value", "$$this.values.srcDesc"] 
           } 
          } 
         } 
        } 
       }, 0] 
      } 
     } 
    }, 
    { 
     $unwind: "$srcDescs" 
    }, 
    { 
     $group: { 
      _id: null, 
      srcDescs: { 
       $addToSet: "$srcDescs" 
      } 
     } 
    } 
]) 
+0

@ Veeram, Danke. Ich werde das heute versuchen. Außerdem bin ich neu in all dem. Haben Sie irgendwelche Links zu einer guten Dokumentation, die mir bei diesem Abwicklungskonzept oder addtoSet-Konzept helfen kann? – Abhinav1singhal

+0

Gern geschehen. Hier finden Sie Links https://docs.mongodb.com/manual/reference/operator/aggregation/addToSet/ und https://docs.mongodb.com/manual/reference/operator/aggregation/unwind/. Sie können Ihre Aggregationspipeline verbessern, wenn Sie auf der Version von Mongo Server 3.4 arbeiten. Lass mich wissen, in welcher Version du bist und ich kann die Antwort aktualisieren. – Veeram

+0

Ja. Wir sind bei db version v3.4.3. Schätzen Sie Ihre Hilfe dazu. – Abhinav1singhal

Verwandte Themen