Main Contents

NoRM, MongoDb and Complex Queries

Schotime @ May 14, 2010

.NET

In my last post I told you about how you can use Regular Expressions to do complex queries in mongodb. In this post I will show you some more features of the Linq Provider.

Updated: 16th May 2010 after some feedback

Take these two classes for example:

    public class User
    {
        public string Id { get; set; }
        public string Name { get; set; }
        public IList<Role> Roles { get; set; }
    }

    public class Role
    {
        public string Name { get; set; }
        public int AccessLevel { get; set; }
    }

and given the following data:

            var standardRole = new Role {Name = "Standard", AccessLevel = 2};
            var adminRole = new Role { Name = "Standard", AccessLevel = 5 };
            var user1 = new User()
            {
                Id = "jbloggs",
                Name = "Joe Bloggs",
                Roles = new List<Role>
                            {
                                standardRole,
                                adminRole
                            }
            };

            var user2 = new User()
            {
                Id = "tsmith",
                Name = "Tony Smith",
                Roles = new List<Role>
                            {
                                standardRole,
                            }
            };

Now say I want to find all users with access level greater than or equal to 5. In Linq-2-sql or plain sql your might write this query like the following.

var query = list.Where(x => x.Roles.Where(y => y.AccessLevel >= 5).Count() > 0).ToList();

This query will not work in the NoRM linq provider, however there is an alternative.

1. var queryforMongo = list.Where(x => x.Roles[0].AccessLevel >= 5).ToList();or
2. var queryforMongo = list.Where(x => x.Roles.Any(y=>y.AccessLevel >= 5)).ToList();

Query 1 here will only return Users where the first role has an access level greater than or equal to 5.

Query 2 will return Users where 1 of the Roles has an access level greater than or equal to 5.

One caveat though. If you try and do a complex query ( one involving an “or” condition or a “and” using the same property ) then you will get an exception. This is because complex queries get converted to a javascript function that cannot be used in the same ways.

Hope this comes in handy for folks out there.

Adam


book mark NoRM, MongoDb and Complex Queries in del.icio.us submit NoRM, MongoDb and Complex Queries to digg.com


3 Comments

  1. Matt June 11, 2010 @ 3:40 am

    In your 2 example queries at the bottom, what type is ‘list’ and how was it created?

  2. Schotime June 14, 2010 @ 1:34 pm

    var db = Mongo.Create(connstring);
    var list = db.getCollection<User>().AsQueryable();

    Hope this helps. If you need further information check the tests in the project at http://github.com/schotime/norm

  3. Vincent July 28, 2010 @ 2:56 am

    I am trying to do something similar using a .Contains() but it’s not working, if I do your trick and do .Any(y => y.Value == category.Value) it works, thanks a lot!

    Is it normal that the contains() of a list of children is not working with NoRM?

Leave a comment

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>


Feed
6,975 spam comments
blocked by
Akismet