У меня часто возникают проблемы с отправкой списка или набора детских объектов 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">
и 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 детей внутри:
У меня часто возникают проблемы с отправкой списка или набора детских объектов c в их p parent и возврат списка p объектов, где каждый p заполнен его c объектами.
Но это труднее вернуть Dataet . Функция агрегации (Spark 3.5.6). < /p> Я начинаю с открытого источника данных CSV, который содержит записи для французских местных органов власти, завершенных городами, которые являются их членами: < /p> [code]L1, C1 L1, C2 L1, C3 L2, C4 L2, C5 [...] < /code> Из файла CSV я извлекал поля примитивов и составил несколько бизнес -объектов. Каждая запись изображает то, что называется периметром [/code]: a Working/DTO-объект, который является описанием члена локального власти. class = "s-table">
. , Lorion, 70, David, null} 185848 false {{, null, null, null, 97410, [...] [...] 2477777 247777 247777 24777 247 /> true < /td> false < /td> < /tr> < /tbody> < /table> < /div> [code]communeMembreGroupement[/code] и membreadherentsyndicatmixte , являющиеся бизнес -объектами, различающимися для каждого периметра , принадлежащего одним и тем же местным органам власти. Города.[code]/** * 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);
/** * 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); } [/code] Вы можете видеть, что в нем отсутствует группа Groupby (...) , что я еще не могу найти, как представить. Но моя нынешняя проблема - его поведение. Когда я отлаживаю его:
[*] Это часто вызывает Zero () Метод агрегатора .
[*] его функция. Управление группы объект, который уменьшается, хорошо заполнен:
[*] mese (...) Zero Object One Side, каждый раз, когда она вызывается. Так что это не слияет ничего на самом деле, я думаю. Члены. /> , но не идеально. Он создавал объекты, но на самом деле не был набором данных , имевший его C детей внутри: [code]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) {
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; } [/code] Итак, в настоящее время, как обходной путь, я заполняю группы , который является LinkedHashset группы siren ([code]String[/code]) Ключ, используя этот метод: [code]public Groupements groupementsAvecMembres(Dataset datasetRowPerimetres, int anneeCOG) { Dataset datasetPerimetres = this.datasetPerimetre.datasetPerimetres(datasetRowPerimetres, anneeCOG); Dataset datasetGroupements = datasetGroupementsSansMembres(datasetRowPerimetres, anneeCOG); Dataset datasetMembresGroupements = this.datasetPerimetre.datasetMembresGroupements(datasetPerimetres);
return super.declinaison(new Groupements(), datasetGroupements, datasetGroupements.col("siren"), Groupement::getSiren, datasetMembresGroupements, datasetMembresGroupements.col("siren"), m -> m.getCommuneMembreGroupement().getSirenCommune(), Groupement::getMembresGroupement); } < /code> И этот тест показывает, что он работает: < /p> // Parametrized by annotation String condition = String.format("sirenGroupement = %s", sirenGroupement);
У меня часто возникают проблемы с отправкой списка или набора детских объектов c в их p parent, и возвращать список p объектов, где каждый p заполнен его c объектами.
Но это труднее вернуть Dataset , что я пробул Sole -Thresse thresse thrafe afe...
У меня часто возникают проблемы с отправкой списка или набора детских объектов c в их p parent и возврат списка p объектов, где каждый p заполнен его c объектами.
Но это труднее вернуть Dataet . Функция агрегации (Spark 3.5.6).
Я начинаю с...
РЕДАКТИРОВАТЬ: В ходе прогресса в этом анализе задачи управление вложенными значениями набора данных с инструментами, которые Spark предлагает с 3.1.x , кажется необходимым.
→ Это моя способность заполнения вложенных списков, карт или наборов...
Редактировать: в ходе прохождения этого анализа задачи управление набором данных вложенных значений с инструментами, которые Spark предлагает с 3.1.x , кажется необходимым.
→ Это моя способ заполнения вложенных списков, карт или наборов вложенных...
РЕДАКТИРОВАТЬ: Переход в этот анализ задачи, управление вложенными значениями набора данных с инструментами, которые Spark предлагает с 3.1.x , кажется, требуется. Преобразовать строки с искойной ской в строку с столбцом карты, что приводит меня к...