2

Following the advice of this article I created a blob index on an array of objects in my documents. For example:

{
...
    "itemID" : 37,
    "MetaData" : [ 
        {
            "FileExtension" : "TXT"
        }, 
        {
            "EmailSubject" : "GAS DESK HEAD MEETING"
        }, 
        {
            "DocumentType" : "EMAIL"
        }, 
        {
            "Date_BestEmailSent" : ISODate("2001-01-26T04:11:32.000Z")
        }, 
        {
            "Date_ParentDate_BestDate" : ISODate("2001-01-26T04:11:32.000Z")
        }, 
        ...
        ],
    ...
}

I'm now parsing a search tree in C# to build a query using the MongoDB C# driver:

IMongoQuery expression; 
switch (leaf.Op)
{
    case SearchOperation.Equals:
        expression = Query.EQ(leaf.Field, leaf.Value);
        break;
    case SearchOperation.Contains:
        expression = Query.Matches(leaf.Field, leaf.Field);
        break;
    ...
}

if (_rootLevelFields.Contains(leaf.Field))
{
    return expression;
}
return Query.ElemMatch("MetaData", expression);

In this case, if my search criteria was FileExtension EQ 'TXT' It would run:

db.test.find({"MetaData": {$elemMatch: {"FileExtension":"TXT"}}})

This runs very slowly and the explain indicates it's scanning all records and not using my Index. If I manually run:

db.test.find({"MetaData": {"FileExtension":"TXT"}})

It uses the index and runs much faster. In this case it appears I don't want to use ElemMatch but the MongoDB Builder namespace doesn't seem to accommodate this type of query e.g.

Query.EQ("MetaData", expression);

is not syntactically correct. I've poured over the documentation and even the MongoDB driver source code but can't find how to do what I want. Am I missing something obvious?

1 Answer 1

1

The EQ method accepts only BSONValue as a parameter, but you're trying to pass a IMongoQuery instance.

In your second query you're basically searching this document in MetaData array :

{"FileExtension":"TXT"}

You will need to create a new BsonDocument and pass it into your EQ method:

Query.EQ("MetaData", new BsonDocument(leaf.Field, leaf.Value));

You can check the documentation for EQ method for more details.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.