Bartosz Kowalczyk
Bartosz Kowalczyk

Reputation: 1519

MongoDB C# Driver -> Check if a string contains an element from a list (of strings)

I am trying to implement quite easy algorithm. Let's say that we have some simple hierarchy: (root) A => B => C Every nove represent some ID and every ID contain many record.

Record have: (string) Id and (List)ExcludedId

So we can have:

rec1:{ Id: A; ExcludedId = [B]}

rec2:{ Id: A; ExcludedId = [D]}

rec3:{ Id: A; ExcludedId = [B]}

rec1':{ Id: A; ExcludedId = []}

rec1":{ Id: C; ExcludedId = []}

rec2':{ Id: D; ExcludedId = []}

Now algorithm looks like:

If I want to take records from C I need to take: C,B,A exist in Id AND C,B,A NOT exists in ExcludedId

So I wrote:

public List<Record> GetRecords(string id, List<string> parentId)
{
    if (parentsIds == null)
            parentsIds = new List<string>();

    var collection = _mongoDbConnection.GetCollection<Records>();

    var allScenarios = parentsIds.ToList();
    allScenarios.Add(Id);

    var myfilter = Builders<Record>.Filter.And(
            Builders<Record>.Filter.Where(record => allScenarios.Any(s => record.Id.Contains(s))),
            Builders<Record>.Filter.Not(Builders<Record>.Filter.Where(record => allScenarios.Any(s => record.ExcludedIds.Contains(s))))
        );

return collection.Find(myfilter).ToList();
}

But I receive an exception which says:

Unsupported filter: Any(value(System.Collections.Generic.List`1[System.String]).Where({document}{Id}.Contains({document}))).'

Can you help me with that? Thank you in advance

Edit:

Changed:

Builders<Record>.Filter.Where(record => allScenarios.Any(s => record.Id.Contains(s))

to

Builders<Record>.Filter.In(ts => ts.ScenarioGuid, parentScenarioGuids),

And that works! But I have problem with

Builders<Record>.Filter.Not(Builders<Record>.Filter.Where(record => allScenarios.Any(s => record.ExcludedIds.Contains(s))))
        );

Because ExcludedIds is List. As a result:

Builders<Record>.Filter.Nin(ts => ts.ExcludedScenarioGuids, allScenarios)

says

Cannot convert lambda expression to type FieldDefinition<Records, string> because it not a delegate type.

Exception is pointed to ts => ts.ExcludedScenarioGuids

Edit2:

Such as @cloudikka wrote, the solution is AnyNin and In. Thanks

Upvotes: 0

Views: 5099

Answers (1)

petesramek
petesramek

Reputation: 3208

You may want to use In method instead of Where method. Alternatively, Nin method. Both can be used for a single value fields. Also there are AnyIn and opposite AnyNin for an array fields.

Related source:

In method

Nin method

AnyIn method

AnyNin method

Upvotes: 2

Related Questions