MongoDB: $graphLookup & Aggregate

Venerdì pomeriggio durante una chiamata col mio collega stavamo parlando di MongoDB per un lavoro ed è uscito in prima analisi uno scenario di lavoro interessante che -abituati a lavorare in SQL Server- ci lasciava spiazzati e con qualche timore.

La domanda che ci siamo posti era semplice ed è la seguente: come fare a riprodurre le CTE recursive in MongoDB?

$graphLookup & Aggregate

Ovviamente il dilemma non ha superato il fine settimana e mi sono messo a studiare subito per risolvere il nostro problema riproducendo il tutto in maniera -molto- minimale.

Ho scoperto che la soluzione -molto più semplice di quanto immaginassi- è ottenibile sfruttando graphLookup assieme ad Aggregate come mostrerà il seguente esempio.

PeopleDTO

Come primo passaggio creiamo un DTO di esempio con una relazione di parentela

  • ID
  • ParentID

In questo modo sara’ possibile risalire la catena e legare i diversi elementi tra di loro

1
2
3
4
5
6
7
public class PeopleDTO
{
	public int ID { get; set; }
	public int ParentID { get; set; }
	public string FirstName { get; set; }
	public string LastName { get; set; }
}

MongoDBHelper

Per semplificare il tutto ho creato la classe MongoDBHelper con questa impronta.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
public class MongoDBHelper
{
	private IMongoCollection<PeopleDTO> _collection = null;
	private readonly string _collectionName = null;


	public MongoDBHelper(string connectionString, string collectionName)
	{
		_collectionName = collectionName;

		MongoClient _client = new MongoClient(connectionString);
		IMongoDatabase _database = _client.GetDatabase(collectionName);
		_collection = _database.GetCollection<PeopleDTO>(collectionName);
	}
	
}	

L’ho definita per mostrarvi come viene definita IMongoCollection tramite la _collectionName fornita nel costruttore.

Query gerarchiche

Ora entriamo nel vivo dell’articolo: come faccio ad effettuare la query gerarchica per avere tutto il legame di parentela? Basterà sfruttare la combinazione di $graphLookup ed Aggregate come mostrato nel seguente esempio

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public string GetGraphLookup()
{

	var graphLookup = new BsonDocument("$graphLookup",
		new BsonDocument
			{
				{ "from", _collectionName },
				{ "startWith", "$ParentID" },
				{ "connectFromField", "ParentID"},
				{ "connectToField",  "ID" },
				{ "as", "reportingHierarchy" },
				{ "maxDepth", 10 }
			}
		);

	var result = _collection
		.Aggregate()
		.AppendStage<BsonDocument>(graphLookup);

	return Newtonsoft
		.Json
		.JsonConvert
		.SerializeObject
		(
			result.ToList()
		);
}

Ho deciso di farvi ritornare un JSON darvi la possibilità’ di

  • Vedere coi vostri occhi il risultato
  • Capire come utilizzarlo nel vostro codice
  • Lasciarvi l’opportunità di mettere mano al codice per fare pratica