MongoDB C#驱动程序 - 执行" IN"的最快方式查询_id

时间:2017-06-12 08:51:16

标签: c# mongodb performance mongodb-query mongodb-.net-driver

我尝试根据ID在特定ID集合中的项目从集合中获取值。

我目前构建过滤器的代码是:

        IEnumerable<string> IDList;

        using (var enumerator = IDList.GetEnumerator())
        {
            if (enumerator.MoveNext() == false) return null; // empty collection

            // take the first key
            var key = enumerator.Current;
            filter = Builders<MyClass>.Filter.Eq(p => p.Key, key);

            // take all the other keys
            while (enumerator.MoveNext())
            {
                var innerKey = enumerator.Current;
                filter = filter | Builders<MyClass>.Filter.Eq(p => p.Key, innerKey);
            }
        }

然后我获取项目的代码是:

        List<MyClass> values = new List<MyClass>();

        using (var cursor = await MyCollection.FindAsync(filter))
        {
            while (await cursor.MoveNextAsync())
            {
                values.AddRange(cursor.Current);
            }
        }

这段代码的性能似乎相当低,而且我确信必须有更快的方法,因为MongoDB应该有非常好的性能...更不用说我查询索引字段了,这应该使查询非常快。无论是以异步方式还是以同步方式,我还能做些什么来加快速度?从一些谷歌搜索我发现有很多方法来查询集合,我不知道哪种方式对我的特定情况最好。

在RoboMongo中运行此查询需要0.02秒,而在C#中运行MongoDb.Driver需要一整秒,有时甚至更长,我不知道为什么。

提前致谢。

1 个答案:

答案 0 :(得分:3)

简单的“$ in”查询怎么样?

using MongoDB.Bson;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    public class MyClass
    {
        public ObjectId Id;
        public string Key;
    }

    public class Program
    {
        static void Main(string[] args)
        {
            IEnumerable<string> ids = new [] { "a", "b", "c" };

            var collection = new MongoClient().GetDatabase("test").GetCollection<MyClass>("test");

            foreach (var id in ids)
            {
                collection.InsertOne(new MyClass { Key = id });
            }

            // here comes the "$in" query
            var filter = Builders<MyClass>.Filter.In(myClass => myClass.Key, ids);

            // sync
            List<MyClass> values = collection.Find(filter).ToList();

            // async
            var queryTask = collection.FindAsync(filter);
            values = GetValues(queryTask).Result;

            Console.ReadLine();
        }

        private static async Task<List<MyClass>> GetValues(System.Threading.Tasks.Task<IAsyncCursor<MyClass>> queryTask)
        {
            var cursor = await queryTask;
            return await cursor.ToListAsync<MyClass>();
        }
    }
}