Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB + C# driver + query array of elements where each array element contains sub-document to query on

Tags:

c#

mongodb

I'm using version 1.5.0.4566 of the official MongoDB C# driver. I'm using Mongo version 2.06.

Here is what my document structure looks like (omitted fields not necessary for this discussion):

{ "Parents" : 
   [ 
     {
     "CreatedOn": ISODate("2012-07-28T15:30:06.623Z"),
     "Title": "Simple Title",
     "Children": [   
                  { "StatusId": 1, "Active" : true, SubChild : { "ExpiresOn": ISODate("2012-07-28T15:30:06.623Z")}},
                  { "StatusId": 1, "Active" : true, SubChild : { "ExpiresOn": ISODate("2012-08-28T15:30:06.623Z")}}
                 ]
     },
     {
     "CreatedOn": ISODate("2012-07-28T15:30:06.623Z"),
     "Title": "Another Simple Title",
     "Children": [   
                  { "StatusId": 1, "Active" : true, SubChild : { "ExpiresOn": ISODate("2012-07-28T15:30:06.623Z")}},
                  { "StatusId": 1, "Active" : true, SubChild : { "ExpiresOn": ISODate("2012-08-28T15:30:06.623Z")}}
                 ]
     }
   ]
}

If I wanted to query the Children that have a StatusId equal to one and Active is true I can use ElemMatch.

Query.ElemMatch("Children", Query.And(Query.EQ("StatusId", 1),Query.EQ("Active",true)));

What I cannot get to work is when I need to include the SubChild element in my query.

Query.ElemMatch("Children", Query.And(Query.EQ("StatusId",1), Query.EQ("Active",true),Query.LT("SubChild.ExpiresOn",DateTime.UtcNow)));

The query doesn't return any values when I try to include the SubChild.ExpiresOn field in the query. I have tried different ways to build this query, but keep getting zero documents when I include the SubChild.ExpiredOn field.

What am I missing?

Thanks,

like image 725
RDotLee Avatar asked Aug 19 '12 03:08

RDotLee


People also ask

Can you use MongoDB with C#?

By developing with C# and MongoDB together one opens up a world of possibilities. Console, window, and web applications are all possible. As are cross-platform mobile applications using the Xamarin framework.

What is a MongoDB driver?

The official MongoDB Node. js driver allows Node. js applications to connect to MongoDB and work with data. The driver features an asynchronous API which allows you to interact with MongoDB using Promises or via traditional callbacks.

Is MongoDB paid?

Is MongoDB Free? You can get started with a MongoDB developer sandbox in MongoDB Atlas for free with basic configuration options. No credit cards are required to provision a cluster, and you can use it to explore and learn more about MongoDB Atlas, the database-as-a-service platform from MongoDB.


1 Answers

Try this instead

Query.ElemMatch("Children", Query.And(Query.EQ("StatusId",1), Query.EQ("Active",true),Query.LT("SubChild.ExpiresOn",DateTime.UtcNow)));

Wondering why this query magically works? It's the case (StatusId vs StatusID). JavaScript is case sensitive.

You could eliminate this problem by using strongly typed Linq queries, like:

from x in collection.AsQueryable()
where x.Children.Any(child => 
    child.StatusId == 1 
    && child.Active 
    && child.SubChild.ExpiresOn < DateTime.UtcNow)
select x
like image 172
kelloti Avatar answered Nov 03 '22 21:11

kelloti