MongoDb c# driver find item in array by field value

后端 未结 4 1114
再見小時候
再見小時候 2020-12-14 01:20

i found the way to check is the value contains in simple array :

var filter = Builders.Filter.AnyEq(x => x.Tags, \"mongodb\");
相关标签:
4条回答
  • 2020-12-14 01:22

    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

    0 讨论(0)
  • 2020-12-14 01:24

    There is ElemMatch

    var filter = Builders<Post>.Filter.ElemMatch(x => x.Tags, x => x.Name == "test");
    var res = await collection.Find(filter).ToListAsync()
    
    0 讨论(0)
  • 2020-12-14 01:39

    As of the 2.4.2 release of the C# drivers, the IFindFluent interface can be used for querying on array element. ElemMatch cannot be used on an array of strings directly, whereas the find interface will work on either simple or complex types (e.g. 'Tags.Name') and is strongly typed.

                FilterDefinitionBuilder<Post> tcBuilder = Builders<Post>.Filter;
                FilterDefinition<Post> tcFilter = tcBuilder.Eq("Tags","mongodb") & tcBuilder.Eq("Tags","asp.net");
                   ...
                await myCollection.FindAsync(tcFilter);
    

    Linq driver uses the aggregation framework, but for a query with no aggregation operators a find is faster.

    Note that this has been broken in previous versions of the driver so the answer was not available at the time of original posting.

    0 讨论(0)
  • 2020-12-14 01:45

    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);
    }
    
    0 讨论(0)
提交回复
热议问题