How to filter an array inside a collection in MONGODB - C #

4

I have the collection PESSOA with a list of Languages as below:

            {
                "_id" : ObjectId("576be476ab76191bec2ff38c"),
                "Nome" : "Nome um",
                "Idiomas" : [ 
                    {
                        "idioma" : "pt-BR",
                        "descricao" : "Brasil"
                    }, 
                    {
                        "idioma" : "en-US",
                        "descricao" : "USA"
                    }, 
                    {
                        "idioma" : "en-EN",
                        "descricao" : "Espanha"
                    }
                ],
                "Idade" : 10
            }

I need to set which Language item should be listed, I got this result in MongoShell with the command below:

            db.getCollection('Pessoas').find({ "_id" : ObjectId("576be476ab76191bec2ff38c")}, 
                {
                    Nome:1,
                    'Idiomas': {$elemMatch: {'idioma': "en-US"}},
                    Idade:1
                })    

And I got the result:

            /* 1 */
            {
                "_id" : ObjectId("576be476ab76191bec2ff38c"),
                "Nome" : "Nome um",
                "Idiomas" : [ 
                    {
                        "idioma" : "en-US",
                        "descricao" : "USA"
                    }
                ],
                "Idade" : 10
            }

Any suggestions on how to do this in C #?

My current code. I have a _id list and I need this list to return with the filtered language:

        List<ObjectId> ListaDeIds = new List<ObjectId>();

        ListaDeIds.Add(new ObjectId("576be476ab76191bec2ff38c"));
        ListaDeIds.Add(new ObjectId("576be47aab76191bec2ff38d"));
        ListaDeIds.Add(new ObjectId("576be47bab76191bec2ff38e"));

        var collection = db.GetCollection<Pessoa>(collectionName);
        var filter = Builders<Pessoa>.Filter.AnyIn("_id", ListaDeIds);

        return await collection.Find<Pessoa>(filter).ToListAsync();
    
asked by anonymous 23.06.2016 / 17:40

1 answer

0

One of the ways to do iso is to Unwind of the array. This is equivalent to making a kind of SelectMany in Linq .

You will have a different object for each language, and then you can filter the languages:

public class Pessoa{
    public string Nome{ get; set; }
    public int Idade { get; set; }
    public ICollection<IdiomaMongo> Idiomas{ get; set; }
}

public class PessoaIdioma{
    public string Nome{ get; set; }
    public int Idade { get; set; }
    public IdiomaMongo Idioma{ get; set; }
}

public class IdiomaMongo{
    public string Descricao{ get; set; }
    public string Idioma{ get; set; }
}

var db = _mongo.GetDatabase("mongoDatabase");
var personMongo = db.GetCollection<Idioma>("Pessoa");

personMongo
.Aggregate()
.Match(filter)
.Unwind<Pessoa, PessoaIdioma>(n => n.Idiomas, new AggregateUnwindOptions<PessoaIdioma>() {
    PreserveNullAndEmptyArrays = true
})
.Match(p => p.Idioma.Idioma == "en-US");
    
21.09.2017 / 16:08