i found the way to check is the value contains in simple array :
var filter = Builders<Post>.Filter.AnyEq(x => x.Tags, "mongodb");
But how to find a complex item with many fields by a concrete field ?
I found the way to write it via the dot notation approach with BsonDocument
builder, but how can i do it with typed lambda notations ?
upd
i think it some kind of
builderInst.AnyIn(p => p.ComplexCollection.Select(ml => ml.Id), mlIds)
but can't check right now, is anyone could help ?
There is ElemMatch
var filter = Builders<Post>.Filter.ElemMatch(x => x.Tags, x => x.Name == "test");
var res = await collection.Find(filter).ToListAsync()
Here's an example that returns a single complex item from an array (using MongoDB.Driver v2.5.0):
Simple Data Model
public class Zoo
{
public List<Animal> Animals { get; set; }
}
public class Animal
{
public string Name { get; set; }
}
Option 1 (Aggregation)
public Animal FindAnimalInZoo(string animalName)
{
var zooWithAnimalFilter = Builders<Zoo>.Filter
.ElemMatch(z => z.Animals, a => a.Name == animalName);
return _db.GetCollection<Zoo>("zoos").Aggregate()
.Match(zooWithAnimalFilter)
.Project<Animal>(
Builders<Zoo>.Projection.Expression<Animal>(z =>
z.Animals.FirstOrDefault(a => a.Name == animalName)))
.FirstOrDefault(); // or .ToList() to return multiple
}
Option 2 (Filter & Linq) This was about 5x slower for me
public Animal FindAnimalInZoo(string animalName)
{
// Same as above
var zooWithAnimalFilter = Builders<Zoo>.Filter
.ElemMatch(z => z.Animals, a => a.Name == animalName);
var zooWithAnimal = _db.GetCollection<Zoo>("zoos")
.Find(zooWithAnimalFilter)
.FirstOrDefault();
return zooWithAnimal.Animals.FirstOrDefault(a => a.Name == animalName);
}
You need the $elemMatch
operator. You could use Builders<T>.Filter.ElemMatch
or an Any
expression:
Find(x => x.Tags.Any(t => t.Name == "test")).ToListAsync()
http://mongodb.github.io/mongo-csharp-driver/2.0/reference/driver/expressions/#elemmatch