Projecting at the request location Requesting an embedded document in a MongoDB collection using C #

Filter the collection in the database instead of memory

I have a model class, save it in the MongoDB collection, then request the same as in my expectation mentioned below.

My model class:

public Class Employee { public ObjectId Id { get; set; } public string EmpID { get; set; } public string EmpName { get; set; } public List<Mobile> EmpMobile { get; set; } public bool IsLive { get; set; } } public Class Mobile { public string MobID { get; set; } public string MobNumber { get; set; } public bool IsPreferred { get; set; } public bool IsLive { get; set; } } 

Values

 List<Employee> EmpInfo = new List<Employee>() { new Employee() { EmpID = "100", EmpName = "John", EmpMobile = new List<Mobile>() { new Mobile() { MobNumber = "55566610", IsPreferred = true, IsLive = false }, new Mobile() { MobNumber = "55566611", IsPreferred = false, IsLive = true }, }, IsLive = true }, new Employee() { EmpID = "101", EmpName = "Peter", EmpMobile = new List<Mobile>() { new Mobile() { MobNumber = "55566610", IsPreferred = true, IsLive = false }, new Mobile() { MobNumber = "55566611", IsPreferred = false, IsLive = false }, }, IsLive = true }, new Employee() { EmpID = "102", EmpName = "Jack", EmpMobile = new List<Mobile>() { new Mobile() { MobNumber = "55566610", IsPreferred = true, IsLive = true }, new Mobile() { MobNumber = "55566611", IsPreferred = false, IsLive = true }, }, IsLive = false } } collectionEmpInfo.InsertMany(EmpInfo); var empList = collectionEmpInfo.Find(new BsonDocument()).ToList(); 

Now I want to select only EmpInfo.IsLive == true inside the embedded document I only need EmpInfo.EmpMobile.IsLive == true modified mobile documents

My expected result:

 List<Employee> EmpInfo = new List<Employee>() { new Employee() { EmpID = "100", EmpName = "John", EmpMobile = new List<Mobile>() { new Mobile() { MobNumber = "55566611", IsPreferred = false, IsLive = true } }, IsLive = true }, new Employee() { EmpID = "101", EmpName = "Peter", EmpMobile = new List<Mobile>() { }, IsLive = true } } 

Please help me write a Where Clause query for my expected output using C # MongoDB .

Note: Filter the collection in the database instead of memory

My libraries and MongoDB connections

 IMongoClient _client = new MongoClient(); IMongoDatabase _database = _client.GetDatabase("Test"); 
0
source share
3 answers

EDIT

IsLive==true added - so the selected array contains only documents, where IsLive==true

I think typed queries are easier to use since c# is a strongly typed language. I used ElemMatch as it is designed to scan an array and is looking for the corresponding element.

 var filterDef = new FilterDefinitionBuilder<Employee>(); var filter = filterDef.Eq(x => x.IsLive, true); var projectDef = new ProjectionDefinitionBuilder<Employee>(); var projection = projectDef.ElemMatch<Mobile>("EmpMobile", "{IsLive:true}"); var empList = collectionEmpInfo.Find(filter).Project<Employee>(projection).ToList(); 
0
source

I think this will solve the problem you have:

 var collection = _database.GetCollection<Employee>("employee"); // (1) var filterBuilder = Builders<BsonDocument>.Filter; var filter = filterBuilder.Eq("IsLive", true) & filterBuilder.Eq("EmpMobile.IsLive", true); // (2) var results = await collection.FindAsync(filter).ToListAsync(); // (3) 

(1): You will need to change the name of the collection with the name of the collection that contains the data you want to request. Also note that it requests TDocument as a generic parameter. Employee does not seem to inherit from TDocument , but you can do this or you can create another DTO class for this purpose.

(2): You can combine conditions using the bit operator AND ( & ).

In addition, you can directly query the internal values โ€‹โ€‹of the array (which you have as a list in your classes). As it turned out, it will return the document if any of the array values โ€‹โ€‹satisfies the condition. In your example, this should return a document for EmpID 100, but it will contain both MobileNumber in it. You have received a document that satisfies the condition, but you have fully retrieved the document.

(3) Finally, rendering the results to a list so that you have them in mind. Alternatively, you can view the results with cursor.MoveNextAsync() , but this will keep your connection to MongoDB more open.

You can find most of the information with examples in Find or Query Data using the MongoDB C # document driver .

0
source

You have several ints for your approach.

first you use collectionEmpInfo.InsertOne(EmpInfo); I assume that you want to use InsertMany instead.

as for filtering by collection, you should know that your filter will affect if the entire object is restored, so adding a filter to the built-in array inside the object will not filter the array, but determine whether the entire object is restored or not depending on whether it is an inline array request condition. My suggestion is to apply the filter only to the employees in the query and filter the result set in memory.

 var filter = filterBuilder.Eq("IsLive", true); var results = await collection.FindAsync(filter).ToListAsync(); 

now filters the collection of results in memory, as in

 var filteredResults = results.ForEach(employee => employee.EmpMobile = employee.EmpMobile.Where(mob => mob.isLive).ToList()); 
0
source

All Articles