66

Assume something like a nested expression

where a = 1 AND ( b = 4 OR b = 5 )

How to use multiple Builders objects and build a complete filter out of such an expression?

2
  • Is this a C# related problem? Do you want to build an expression dynamically? Commented Aug 26, 2015 at 13:12
  • I am sorry to keep the question incomplete. Yes, it's using C# driver 2.0 Builder classes. Yes, I want to build the expression into FilterDefinition dynamically. Commented Aug 27, 2015 at 4:35

3 Answers 3

147

Builders is really flexible class, it also has overridden operators "& = AND" and "| = OR"

Your example will be

var filter = Builders<User>.Filter.Eq(x => x.A, "1");
filter &= (Builders<User>.Filter.Eq(x => x.B, "4") | Builders<User>.Filter.Eq(x => x.B, "5"));
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks! I'll try to use this approach. The difficult part will be parsing the string based expression and building the nested FilterDefinition. Because when I parse the string into filter objects, I will go left to right and and will have to start with outer most builder and then navigate to child builders...may be I need some tree data structure
best answer.. congrats!!
you'll definitely need to build a tree to do this correctly. Sounds like a fun project
The other thing I'd consider here is that you don't need multiple builder objects. You can use the same builder for multiple filters.
You can use: filter &= (Builders<User>.Filter.Eq(x => x.B, "4")
|
27

if you want conditionally add more filters use this method:

var builder = Builders<Student>.Filter;
var filter = builder.Empty;

if (!string.IsNullOrWhiteSpace(firstName))
{
   var firstNameFilter = builder.Eq(x => x.FirstName, firstName);
   filter &= firstNameFilter;
}

if (!string.IsNullOrWhiteSpace(lastName))
{
   var lastNameFilter = builder.Eq(x => x.LastName, lastName);
   filter &= lastNameFilter;
}

if (minAge != null && maxAge != null)
{
   var ageFilter = builder.And(builder.Gt(x => x.Age, minAge),
      builder.Lt(x => x.Age, maxAge));
   filter &= ageFilter;
}

var result = await _plpResultCollection.Find(filter).ToListAsync();

2 Comments

thats what I came here for :)
This doesn't work if you use or (|=) expression, it will return all collections because of builder.empty
20

You can use very simply like this way.....

var filter = Builders<Rental>.Filter.Where(s => s._id== id && s.Price==1500);

1 Comment

Although this doesn't answer the OPs question, it did help me on "my mission".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.