Dans mes documents, j'ai le _id, un nom de société et un sponsor (qui identifie le document parent, par le _id).
Par exemple, j'ai ce premier enregistrement qui n'a pas de sponsor (parent)
_id:607536219910ef23e80e0bbe
companyname:"Société principale"
sponsor:"
Ensuite Company 1, où la Société principale est le parent:
_id:607e16760a9d2c16e06bc252
companyname:"Société 1"
sponsor:"607536219910ef23e80e0bbe"
Et Company 2, où la Société 1 est le parent:
_id:607e187b0a9d2c16e06bc253
companyname:"Société 2"
sponsor:"607e16760a9d2c16e06bc252"
Et Company 3, où la Société 2 est le parent:
_id:607e1f470a9d2c16e06bc254
companyname:"Société 3"
sponsor:"607e187b0a9d2c16e06bc253"
Je fais un $match pour ramener les enregistrements enfants pour la société principale
{
sponsor: '607536219910ef23e80e0bbe'
}
Et ensuite, je $addFields userid, qui est un _Id converti en chaîne. Ceci est pour correspondre plus tard avec le sponsor:
{"userid": { "$toString": "$_id" }}
Maintenant, lorsque je graphLookup, j'obtiens la société fille (Société 2) pour la Société principale, mais je n'obtiens pas la Société 3 en tant que fille de la Société 2. Je n'obtiens que la Société 1 et la Société 2:
Voici mon graphLookup
{
from: 'pls',
startWith: "$userid",
connectFromField: 'userid',
connectToField: 'sponsor',
as: 'downline',
maxDepth: 100,
restrictSearchWithMatch: {}
}
Toute aide sera appréciée.
MISE À JOUR:
Comme l'a dit Turivishal ci-dessous, la requête fonctionne, mais voici les résultats attendus:
[{
"_id": "607536219910ef23e80e0bbe",
"companyname": "Société principale",
"downline": [{
"_id": "607e16760a9d2c16e06bc252",
"companyname": "Société 1",
"sponsor": "607536219910ef23e80e0bbe",
"downline": [{
"_id": "607e187b0a9d2c16e06bc253",
"companyname": "Société 2",
"sponsor": "607e16760a9d2c16e06bc252",
"downline": [{
"_id": "607e1f470a9d2c16e06bc254",
"companyname": "Société 3",
"sponsor": "607e187b0a9d2c16e06bc253"
}]
}]
}],
"sponsor": "",
"userId": "607536219910ef23e80e0bbe"
}
SOLUTION PAR TURIVISHAL:
Comme solution Turivishal, voici le pipeline final qui fournit une vue hiérarchique/arborescente parfaite de la requête récurrente et fonctionne parfaitement avec les contrôles Angular Treeview. Merci beaucoup Turivishal. Je pense que vous devriez poster une réponse pour que je puisse l'accepter et qu'elle puisse être utile pour d'autres.
Sa solution est assez similaire à celle qu'il a proposée, mais bien meilleure. J'ai fini par créer un nouveau champ appelé PLID qui duplique le champ _id, et cela fonctionne incroyablement bien. Je laisse les administrateurs décider s'ils estiment que cette question devrait être fermée, car encore une fois, la solution de Turivishal est basée sur cette question, mais plus claire à mon avis. Voici son travail:
[
{
'$match': {
'sponsor': '0'
}
}, {
'$graphLookup': {
'from': 'pls',
'startWith': '$plid',
'connectFromField': 'plid',
'connectToField': 'sponsor',
'depthField': 'level',
'as': 'children'
}
}, {
'$unwind': {
'path': '$children',
'preserveNullAndEmptyArrays': true
}
}, {
'$sort': {
'children.level': -1
}
}, {
'$group': {
'_id': '$plid',
'sponsor': {
'$first': '$sponsor'
},
'companyname': {
'$first': '$companyname'
},
'children': {
'$push': '$children'
}
}
}, {
'$addFields': {
'children': {
'$reduce': {
'input': '$children',
'initialValue': {
'level': -1,
'presentChild': [],
'prevChild': []
},
'in': {
'$let': {
'vars': {
'prev': {
'$cond': [
{
'$eq': [
'$$value.level', '$$this.level'
]
}, '$$value.prevChild', '$$value.presentChild'
]
},
'current': {
'$cond': [
{
'$eq': [
'$$value.level', '$$this.level'
]
}, '$$value.presentChild', []
]
}
},
'in': {
'level': '$$this.level',
'prevChild': '$$prev',
'presentChild': {
'$concatArrays': [
'$$current', [
{
'$mergeObjects': [
'$$this', {
'children': {
'$filter': {
'input': '$$prev',
'as': 'e',
'cond': {
'$eq': [
'$$e.sponsor', '$$this.plid'
]
}
}
}
}
]
}
]
]
}
}
}
}
}
}
}
}, {
'$addFields': {
'children': '$children.presentChild'
}
}
]