Search code examples
c#mongodbmongodb-.net-driver

Selecting on document "outside" of join while filtering on documents "within" join?


I have two IMongoCollections holding documents of type Person and Animal respectively.

public class Person
{
    public Guid PersonId { get; set; } = Guid.NewGuid();
    public Guid PetId { get; set; }
}

public class Animal
{
    public Guid AnimalId { get; set; } = Guid.NewGuid();
    public bool IsMammal { get; set; } 
}
...
Animal bootsTheMonkey = new Animal() { IsMammal = true };
Person doraTheExplorer = new Person() { PetId = bootsTheMonkey.AnimalId };

I am trying to write a query which finds "all persons whose pets are mammals".

var query =
    from pDoc in PersonDocumentCollection.AsQueryable()
    where !pDoc.PetId.Equals(Guid.Empty)
    join aDoc in AnimalDocumentCollection.AsQueryable() on pDoc.PetId equals aDoc.AnimalId
        where aDoc.IsMammal
    select pDoc;

Though this query is incorrect evidenced by the error message

$project or $group does not support {document}.

From searching it looks like this error comes about from the use of where aDoc.IsMammal, more specifically the use of the aDoc within/after the join (Based on this SO question). Though I am not entirely sure if that is the issue.


Overall I am trying to join two IMongoCollections where the first's documents have a field whose value is the BsonId of a document from another collection. Then once joined I would like to first the documents from the first collection on the values of fields in the second.


Solution

  • You could try to do something like this (assuming allPeople is a list of all your Person objects and allAnimals is all your Animal objects):

    var query = allPeople    
                .Join(allAnimals, 
                      p => p.PetId,        
                      a => a.AnimalId,   
                      (p, a) => new { P = p, A = a }) 
                .Where(PA => PA.A.IsMammal == true);    
    

    https://dotnetfiddle.net/8lw5ye