2016-10-09 4 views
0

Ich habe unter 3 Dokumente. Jeweils ein Kontakt für einen Benutzer:Gruppierung Mongo-Dokumente mit Elementen der Array-Feld

{ 
    "_id" : ObjectId("57f9f9f3b91d070315273d0d"), 
    "profileId" : "test", 
    "displayName" : "duplicateTest", 
    "email" : [ 
     { 
      "emailId" : "[email protected]" 
     }, 
     { 
      "emailId" : "[email protected]" 
     }, 
     { 
      "emailId" : "[email protected]" 
     } 
    ] 
} 
{ 
    "_id" : ObjectId("57f9fab2b91d070315273d11"), 
    "profileId" : "test", 
    "displayName" : "duplicateTest2", 
    "email" : [ 
     { 
      "emailId" : "[email protected]" 
     } 
    ] 
} 
{ 
    "_id" : ObjectId("57f9fcefb91d070315273d15"), 
    "profileId" : "test", 
    "displayName" : "duplicateTest2", 
    "email" : [ 
     { 
      "emailId" : "[email protected]" 
     } 
    ] 
} 

ich aggregieren müssen/Gruppe sie von Array-Elementen, so dass ich den doppelten Kontakt (auf E-Mail-ID basiert) identifizieren kann. Da es eine gemeinsame E-Mail-ID zwischen doc (1 & 2) und doc (1 & 3) gibt, repräsentieren diese 3 einen Kontakt und sollten in einem als ein Kontakt zusammengeführt werden.

Ich versuchte dies, wie unten mit zu tun $ entspannen und $ Gruppe in java:

List<DBObject> aggList = new ArrayList<DBObject>(); 

     BasicDBObject dbo = new BasicDBObject("$match", new BasicDBObject("profileId", "0fb72dcf-292b-4343-a0e7-1d613a803b1e")); 

     aggList.add(dbo); 

     BasicDBObject dboUnwind = new BasicDBObject("$unwind", "$email"); 
     aggList.add(dboUnwind); 



     BasicDBObject dboGroup = new BasicDBObject("$group", 
       new BasicDBObject().append("_id", new BasicDBObject("name", "$email.emailId")) 
         .append("uniqueIds", new BasicDBObject("$addToSet", "$_id")) 
         .append("count", new BasicDBObject("$sum", 1))); 

     aggList.add(dboGroup); 

     BasicDBObject dboCount = new BasicDBObject("$match", new BasicDBObject("count", new BasicDBObject("$gte", 2))); 
     aggList.add(dboCount); 


     BasicDBObject dboSort = new BasicDBObject("$sort", new BasicDBObject("count",-1)); 
     aggList.add(dboSort); 


     BasicDBObject dboLimit = new BasicDBObject("$limit", 10); 
     aggList.add(dboLimit); 


     AggregationOutput output = collection.aggregate(aggList); 


    System.out.println(output.results()); 

Diese Gruppen docs per E-Mail-ID (und zu Recht), aber dient nicht dem Zweck.

Jede Hilfe würde sehr geschätzt werden.

Ich muss die Funktion implementieren, wo Benutzer über die möglichen doppelten Kontakte in seinem Repository aufgefordert werden können. Ich brauche Aggregation Ergebnis so etwas wie:

[ 
    { 
     "_id":{ 
     "name":[ 
      { 
      "emailId" : "[email protected]" 
     }, 
     { 
      "emailId" : "[email protected]" 
     }, 
     { 
      "emailId" : "[email protected]" 
     } 
     ] 
     }, 
     "uniqueIds":[ 
     { 
      "$oid":"57f9fcefb91d070315273d15" 
     }, 
{ 
      "$oid":"57f9fcefb91d070315273d11" 
     }, 
{ 
      "$oid":"57f9fcefb91d070315273d15" 
     } 
     ], 
     "count":3 
    }, 

Also im Grunde, ich brauche _id für alle möglichen doppelten Kontakte (es könnte wie oben eine andere Gruppe von Duplikaten mit _ids Liste sein), so dass ich es Benutzer auffordern kann und Benutzer kann sie nach seinem Willen zusammenführen. Hoffe es ist jetzt klarer. Vielen Dank!

+0

Sie in einem Dokument zusammengefasst bedeuten Sie? Möchten Sie das Duplikat löschen oder nur das Duplikat identifizieren? – notionquest

+0

Bitte definieren Sie Ihren Zweck klar, denn wenn ich die Aggregation in Ihrem Code zur Verfügung gestellt, funktioniert es in Ordnung. Es gibt neue Dokumente zurück, in denen Profile in 1 zusammengeführt werden. Damit könnten Sie etwas aufräumen oder zusammenführen. So vermisse ich, was Sie vermissen :) – HoefMeistert

+0

@notionquest Ich muss identifizieren und Benutzer zuerst auffordern. Wenn er sich dazu entschließt, das kann ich später machen –

Antwort

0

Nun, Ihre Frage unterscheidet sich ein wenig von dem Ergebnis, das Sie suchen. Ihre inital Frage wies mich auf die folgende Aggregation:

db.table.aggregate(
    [ 
    { 
     $unwind: "$email" 
    }, 
    { 
     $group: { 
     _id : "$email.emailId", 
     duplicates : { $addToSet : "$_id"} 
     } 
    } 
    ] 
); 

Daraus ergibt sich:

{ 
    "_id" : "[email protected]", 
    "duplicates" : [ 
     ObjectId("57f9f9f3b91d070315273d0d") 
    ] 
} 
{ 
    "_id" : "[email protected]", 
    "duplicates" : [ 
     ObjectId("57f9fcefb91d070315273d15"), 
     ObjectId("57f9f9f3b91d070315273d0d") 
    ] 
} 
{ 
    "_id" : "[email protected]", 
    "duplicates" : [ 
     ObjectId("57f9fab2b91d070315273d11"), 
     ObjectId("57f9f9f3b91d070315273d0d") 
    ] 
} 

per EMail gruppierte.

Aber die Beispielausgabe Sie zu Ihrer Frage hinzugefügt haben diese Aggregation:

db.table.aggregate(
    [ 
    { 
     $unwind: "$email" 
    }, 
    { 
     $group: { 
     _id : "$profileId", 
     emails : { $addToSet : "$email.emailId"}, 
     duplicates : { $addToSet : "$_id"} 
     } 
    } 
    ] 
); 

was zur Folge hat:

{ 
    "_id" : "test", 
    "emails" : [ 
     "[email protected]", 
     "[email protected]", 
     "[email protected]" 
    ], 
    "duplicates" : [ 
     ObjectId("57f9fcefb91d070315273d15"), 
     ObjectId("57f9fab2b91d070315273d11"), 
     ObjectId("57f9f9f3b91d070315273d0d") 
    ] 
} 
+0

Diese zweite Lösung ist nicht akkumuliert. Es gruppiert nur alle Kontakte nach profileId. Was ich will, ist für eine bestimmte Profil-ID (in diesem Fall * test *) alle Kontakte, wo E-Mail-Array eine gemeinsame E-Mail-ID (direkt oder transitiv) hat, sollten gruppieren. Es kann offensichtlich mehrere solche Gruppen geben. Ich werde versuchen, mit Hilfe von einfachen Beispiel zu erklären lässt sagen, ein Benutzer mit userid "test1" ist eingeloggt. Er wird eine "Dubletten finden" -Taste haben. Wenn er darauf klickt, sollte er die Gruppierung sehen (wenn Sie eine in Google Mail gesehen haben (Option zum Suchen und Zusammenführen von Duplikaten)). Beispiel im nächsten Kommentar. –

+0

zum Beispiel: contact1 {profileid: test1, email: ["a", "b"]} kontakt 2: {profilid: test1, email: ["a"]} kontakt 3: {profileid: test1, email: ["b"]} Kontakt 4: {profileid: test1, email: ["p"]} Kontakt 5: {profileid: test1, email: ["p", "q"]} Jetzt seit Kontakt 2 & Kontakt 3 habe keine direkte gemeinsame E-Mail-ID, aber jede hat eine gemeinsame E-Mail-ID mit Kontakt 1 Wir sollten dem Benutzer mitteilen, dass Kontakt 1 & 2 & 3 potentielle Duplikate sind. Auch gleich für Kontakt 4 & 5. so sollte eine Ausgabe so etwas wie sein: –

+0

[{ "_id": "test", "E-Mails": [ "a", "b", ], "Duplikate": [ 1,2 , 3 ] }, { "_id": "Test" "E-Mails": [ „p“, „q“, ], "Dubletten": [ 4,5 ] } ] –