简体   繁体   中英

C# MongoDB driver very slow on text search

I have a wildcard text search over a collection with a million documents.

I can use my full text index directly from the MongoDB console with:

 db.oneMillionDocumentsIndexed.find({$text: { $search: "raven" } } )

and this returns document after a minute-ish.

When I try the same thing in a unit test though, test runs for over half an hour without returning any documents:

[Test]
public void SearchTextFullText()
{
    var credential = MongoCredential.CreateCredential("test", "readonlyUser", "password");
    var settings = new MongoClientSettings
                   {
                       Credentials = new[] { credential },
                       Server = new MongoServerAddress("localhost")
                   };

    var mongoClient = new MongoClient(settings);

    var database = mongoClient.GetDatabase("test");

    var collection = database.GetCollection<BsonDocument>("oneMillionDocumentsIndexed");

    var searchWord = "raven";

    var filter = Builders<BsonDocument>.Filter.Text(searchWord);


    var documentCount = 0;


    var stopwatch = new Stopwatch();

    stopwatch.Start();
    using (var cursor = collection.FindAsync(filter).Result)
    {
        while (cursor.MoveNext())  // <-- We never get past this point
        {
            var batch = cursor.Current;

            foreach (var document in batch)
            {
                Console.WriteLine(document["_id"].AsObjectId.ToString());
                Assert.That(document, Is.Not.Null);
                documentCount++;
            }

        }
    }
    stopwatch.Stop();

    Console.WriteLine($"Found {documentCount} documents.  Total time {stopwatch.ElapsedMilliseconds}ms.  Avg. {stopwatch.ElapsedMilliseconds / documentCount}");
}

It did finally finish: Found 158791 documents. Total time 1670368ms. Avg. 10

Do 27mins and 50 seconds.

Task.Result is a blocking call (in this case collection.FindAsync(filter).Result), it will wait until full result set is computed and then it will return.

you can try this code and i'm sure it will perform better (though not tested)

using(var cursor = await collection.Find(filter).ToCursorAsync())
{
    while(await cursor.MoveNextAsync())
    {
        //rest of logic ....

不知道您使用的是哪个版本的mongoDb驱动程序,但是可以尝试一下

 while (cursor.MoveNextAsync().Result)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM