1

I have a collection of documents that can contain criteria grouped into categories. The structure could look like this:

{
     "Name": "MyDoc",
     "Criteria" : [
         {
             "Category" : "Areas",
             "Values" : ["Front", "Left"]
         },
         {
             "Category" : "Severity",
             "Values" : ["High"]
         }
      ]
}

The class I'm using to create the embedded documents for the criteria looks like this:

public class CriteriaEntity
{
    public string Category { get; set; }
    public IEnumerable<string> Values { get; set; }
}

The user can choose criteria from each category to search (which comes into the function as IEnumerable<CriteriaEntity>) and the document must contain all the selected criteria in order to be returned. This was my first attempt:

var filterBuilder = Builders<T>.Filter;
var filters = new List<FilterDefinition<T>>();

filters.Add(filterBuilder.Exists(entity => 
    userCriterias.All(userCriteria => 
        entity.Criteria.Any(entityCriteria => 
            entityCriteria.Category == userCriteria.Category
            && userCriteria.Values.All(userValue =>
                entityCriteria.Values.Any(entityValue =>
                    entityValue == userValue))))));

However I get the error: "Unable to determine the serialization information for entity...". How can I get this to work?

adam0101
  • 29,096
  • 21
  • 96
  • 174
  • Hi, in MongoDB, "nested" elements or inner elements are called "Documents", look for IBsonDocumentSerializer, and interfaces so you can apply them to your entities. – celerno Jun 03 '15 at 15:59

1 Answers1

1

MongoDB.Driver 2.0 doesn't support Linq.All. Anyway you task can be resolve next way:

var filterDefinitions = new List<FilterDefinition<DocumentEntity>>();
foreach (var criteria in searchCriterias)
{
        filterDefinitions
           .AddRange(criteria.Values
           .Select(value => new ExpressionFilterDefinition<DocumentEntity>(doc => doc.Criterias
               .Any(x => x.Category == criteria.Category && x.Values.Contains(value)))));
}

var filter = Builders<DocumentEntity>.Filter.And(filterDefinitions);
return await GetCollection<DocumentEntity>().Find(filter).ToListAsync();
rnofenko
  • 9,198
  • 2
  • 46
  • 56