У меня часто возникают проблемы с отправкой списка или набора детских объектов c в их p parent и возврат списка p объектов, где каждый p заполнен его c объектами.
Но это труднее вернуть Dataet . Функция агрегации (Spark 3.5.6). < /p>
Я начинаю с открытого источника данных CSV, который содержит записи для французских местных органов власти, завершенных городами, которые являются их членами: < /p>
L1, C1
L1, C2
L1, C3
L2, C4
L2, C5
[...]
< /code>
Из файла CSV я извлекал поля примитивов и составил несколько бизнес -объектов. Каждая запись изображает то, что называется периметром : a Working/DTO-объект, который является описанием члена локального власти. class = "s-table">
categoriembresgroupement < /th>
communemembregement < /th>
competencexercees < /th>
densitedemographiquiquebipanceabitansaukarexercees < /th>
densitedemographiquiquiquiquipanciqueBitansaukileCaRceeses. /> etablissementPublicterRitoriAldebassin < /th>
fiscalitefinancement < /th>
fiscalitepropre < /th>
Gestiondeaux < /th>
Interpectomental < /th> /> MembreadherentSyndicatmixte < /th>
naturejuridique < /th>
noMgroupement < /th>
nombredecommunesmmebres < /th>
Organigramme < /th>
< /th>
Organigramme < /th>
< /th>
. /> redevanceEnleVementordersmenageres < /th>
siege < /th>
siren < /th>
TaxeEnleventordersmenageres < /th>
ZoneDemontagne < /th>
zonedemontagn />
Commune < /td>
{97401, {974}, {04}, Les Avirons, 218, 11445, 11663, 219740016} < /td>
{Null, {C1020 -> {C1020 -> {C1020 -> {C1020 -> {C1020 -> {C1020 -> {C1020 -> {C1020 -> {C102016 NULL}, C1505 -> {C1505, false, false, NULL}, [...]
491.7
NULL
{NULL, 4108814, NULL, 9325112, 5216298, FPU, NULL, NULL, NULL, NULL, NULL, NULL}
true
null
false
{ile de la réunion mobilés, 891190, 200045276}
communaute_agglomeration < /td>
CA Civis (Communauté Intercommunale des Villes Solidaires) < /td>
6 < /td>
{m. />185848
false
{{ , NULL, NULL, NULL, 97410,[...] [...]
249740077
true
false
< /tr>
commune < /td>
{97404, {974}, {04}, L'Etang -salé, 211, 14329, 14540, 219740040} < /td>
{null> {null> . {C1020, false, false, null}, c1505 -> {c1505, false, false, null}, [...] < /td>
td>491.7
null < /td>
{null, 4108814, null, 93512, 9, 5212, 9, 9312, 9, 9312, 9312, 9312, 9, 9312, 9, 9, 9312, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 5112, 9, 9, 9, 512, 9, 5112, 9, FPU, NULL, NULL, NULL, NULL, NULL, NULL}
true
NULL
false
{SM de Pierrefonds, 356662, 259741007}
communaute_agglomeration < /td>
CA Civis (Communauté Intercommunale des Villes Solidaires) < /td>
6 < /td>
{m. />185848
false
{{ , NULL, NULL, NULL, 97410,[...] [...]
249740077
true
false
commune
{97405, {974}, {04}, Petite-Île, 171, 12920, 13091, 219740057}
{NULL, {C1020 -> {C1020, false, false, null}, c1505 -> {c1505, false, false, null}, [...] < /td>
491.7
null < /td>
{null, 410814, null, 9325112, 5298, 5, null, 4108814, null, 9325112, 5298, 5, 5, 5298, 5, 5298, 5, 5298, 5, 5298, 5, 51629, 5, 5, 516129, 5, 5, 5, 51629, 5, 51629, 5, 5, 529, 51629, 5, 5, 529, 529, 529, 516 298, 516 298, 516129, NULL, NULL, NULL, NULL, NULL}
TRUE
null
false
{saep des hirondelles, 320612, 2001079}
communaute_agglomeration < /td>
CA Civis (Communauté Intercommunale des Villes Solidaires) < /td>
6 < /td>
{m. />185848
false
{{ , NULL, NULL, NULL, 97410,[...] [...]
249740077
true
false
< /tr>
commune < /td>
{97414, {974}, {04}, Saint -Louis, 676, 54478, 55154, 219740149} < /td>
{null> {null> {null> {null> {null> {nul {C1020, false, false, null}, c1505 -> {c1505, false, false, null}, [...] < /td>
td>491.7
null < /td>
{null, 4108814, null, 93512, 9, 5212, 9, 9312, 9, 9312, 9312, 9312, 9, 9312, 9, 9, 9312, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 5112, 9, 9, 9, 512, 9, 5112, 9, FPU, NULL, NULL, NULL, NULL, NULL, NULL} < /td>
true < /td>
null < /td>
false < /td>
{sm d'études et de du Scot du Grand Sud, 320611, 3206, 32011, 3206, 3206, 3206, 3201, 3201, 3206, 3206, 3201, 3201, 3201, 3201, 3206, 3201, 3201, 3201, 3201, 3201, 32011, 32011, 3201, 3201, 3201, 32011, 3201, 3201, 3201, 32011, 32011 259741080} < /td>
communaute_agglomeration < /td>
ca civis (communauté intercommunale des villes solides) < /td>
6 < /td>
{m. Null}
185848
false
{{, null, null, null, 97410, [...] [...]
24740077
24740077 /> false < /td>
< /tr>
commune < /td>
{97416, {974}, {04}, Saint-Pierre, 886, 85254, 86140, 2197400164} < /td> < /td> < /td> < /td> < /td> < /td> < /td> < /td> < /td> < /td> < /td> < /td> < /td> < /td> < /td> < /td> < /td> < /td> < /td> < /td> < /td> /> {null, {c1020 -> {c1020, false, false, null}, c1505 -> {c1505, false, false, null}, [...] < /td>
td>491.7> nul NULL, 9325112, 5216298, FPU, NULL, NULL, NULL, NULL, NULL, NULL} < /TD>
TRUE < /TD>
NULL < /td>
FALSE < /td>
{SM DECHETS DETHERS DESE DETORE DETORE DETHERS DETHERS DETORE < /td> Ouest de la réunion dénommé ileva, 542144, 200045342}
communaute_agglomeration
CA Civis (Communauté Intercommunale des Villes Solideres)
6 6 . /> {m., Rdc,, Lorion, 70, David, Null} < /td>
185848 < /td>
false < /td>
{, null, null, null, 97410, [...] [...] < /td>
/> 249740077 < /td>
true < /td>
false < /td>
< /tr>
commune < /td>
{97424, {974}, {04}, {04}, {04}, {04}, {04). 5215, 5260, 219740248/ /> null < /td>
{null, 4108814, null, 9325112, 5216298, FPU, NULL, NULL, NULL, NULL, NULL, NULL} < /TD>
< /td>
nul /> false < /td>
{, null,} < /td>
communaute_agglomeration < /td>
ca civis (communauté intercommunale des villes solides) < /td>
6 < /td>
. , Lorion, 70, David, null}
185848
false
{{, null, null, null, 97410, [...] [...]
2477777
247777
247777 24777 247 /> true < /td>
false < /td>
< /tr>
< /tbody>
< /table> < /div>
communeMembreGroupement и membreadherentsyndicatmixte , являющиеся бизнес -объектами, различающимися для каждого периметра , принадлежащего одним и тем же местным органам власти. Города./**
* Agrégateur de {@link Perimetre} en {@link Groupement}
* @author Marc Le Bihan
*/
public class GroupementAggregator extends Aggregator
{
@Serial
private static final long serialVersionUID = 1861686194387336535L;
/**
* Renvoyer une valeur neutre pour cette aggrégation
* @return groupement vide
*/
@Override
public Groupement zero() {
Groupement zero = new Groupement();
zero.setNatureJuridique(NatureJuridiqueGroupement.METROPOLE_LYON);
zero.setMembresGroupement(new MembresGroupement());
return zero;
}
/**
* Combine deux valeurs pour en créer une autre (il est possible qu'elle modifie l'objet {@link Groupement} soumis plutôt que d'en créer un autre.
* @param groupement Groupement à réduire (cumuler dedans)
* @param perimetre Périmètre à considérer
* @return Groupement réduit
*/
@Override
public Groupement reduce(Groupement groupement, Perimetre perimetre) {
// Si le groupement que l'on nous soumet est vide, il s'agit de celui créé par la fonction zero.
// Mais il ne nous intéresse pas, et nous préférons recréer un vrai groupement, une première fois, d'après le périmètre reçu.
Groupement groupementReduit = groupement.getSiren() == null ? new Groupement(perimetre) : new Groupement(groupement);
if (groupementReduit.getMembresGroupement() == null) {
groupementReduit.setMembresGroupement(new MembresGroupement());
}
MembreGroupement membre = new MembreGroupement(perimetre);
groupementReduit.getMembresGroupement().add(membre);
return groupementReduit;
}
/**
* Fusionner deux valeurs intermédiaires
* @param a Premier {@link Groupement}
* @param b Deuxième {@link Groupement}
* @return Groupement déduit
*/
@Override
public Groupement merge(Groupement a, Groupement b) {
// Si l'un des groupements est le zéro, retourner l'autre
if (a.getSiren() == null) {
return b;
}
if (b.getSiren() == null) {
return a;
}
// FIXME : Fait un aggregate ici, mais sans tenir compte d'un group by qu'il faudrait faire avant
a.getMembresGroupement().addAll(b.getMembresGroupement());
return a;
}
/**
* Transformer la sortie après réduction
* @param reduction Contenu réduit
* @return {@link Groupement} final
*/
@Override
public Groupement finish(Groupement reduction) {
// Pas de modification à apporter à l'objet final
return reduction;
}
/**
* Renvoyer l'encodeur du type intermédiaire
* @return Encodeur de {@link Groupement}
*/
@Override
public Encoder bufferEncoder() {
return Encoders.bean(Groupement.class);
}
/**
* Renvoyer l'encodeur du type final
* @return Encodeur de {@link Groupement}
*/
@Override
public Encoder outputEncoder() {
return Encoders.bean(Groupement.class);
}
}
< /code>
И я использую его таким образом: < /p>
public Dataset datasetGroupementsAvecMembres(Dataset datasetPerimetre) {
GroupementAggregator agreggateurGroupement = new GroupementAggregator();
TypedColumn groupements = agreggateurGroupement.toColumn().name("mG");
return datasetPerimetre.select(groupements);
}
Вы можете видеть, что в нем отсутствует группа Groupby (...) , что я еще не могу найти, как представить. Но моя нынешняя проблема - его поведение. Когда я отлаживаю его:
[*] Это часто вызывает Zero () Метод агрегатора .
[*] его функция. Управление группы объект, который уменьшается, хорошо заполнен:
[*] mese (...)
Zero Object One Side, каждый раз, когда она вызывается. Так что это не слияет ничего на самом деле, я думаю. Члены. />
, но не идеально. Он создавал объекты, но на самом деле не был набором данных , имевший его C детей внутри:
public Entreprises entreprises(Dataset entreprises, Dataset etablissements) {
return super.declinaison(new Entreprises(),
entreprises, SIREN_ENTREPRISE.col(entreprises), Entreprise::getSiren,
etablissements, SIREN_ENTREPRISE.col(etablissements), Etablissement::getSiret,
Entreprise::getEtablissements);
}
< /code>
с: < /p>
public C declinaison(C ensemble,
Dataset parents, Column columnJoinP, Function obtenirClefDuParent,
Dataset enfants, Column columnJoinE, Function obtenirClefEnfant,
Function obtenirMapEnfants) {
Dataset ds = parents.joinWith(enfants, columnJoinP.equalTo(columnJoinE), "inner");
for(Tuple2 tuple : ds.collectAsList()) {
// Rechercher l'objet parent par KP, et l'ajouter à l'ensemble C, vide, s'il n'existe pas.
P source = tuple._1();
KP clefSourceParent = obtenirClefDuParent.apply(source);
P parent = ensemble.computeIfAbsent(clefSourceParent, clef -> tuple._1());
// Dans cet objet parent P, rechercher la liste des enfants E, indexée par KE, et y ajouter notre instance de E.
Map ensembleEnfants = obtenirMapEnfants.apply(parent);
E nouvelEnfant = tuple._2();
KE clefEnfant = obtenirClefEnfant.apply(nouvelEnfant);
ensembleEnfants.put(clefEnfant, nouvelEnfant);
}
return ensemble;
}
Подробнее здесь: https://stackoverflow.com/questions/797 ... ies-into-t