首页 文章

使用C#驱动程序在MongoDB中搜索对象数组

提问于
浏览
2

按照this article的建议,我在文档中的对象数组上创建了一个blob索引 . 例如:

{
...
    "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")
        }, 
        ...
        ],
    ...
}

我现在正在使用MongoDB C#驱动程序在C#中解析搜索树以构建查询:

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);

在这种情况下,如果我的搜索条件是 FileExtension EQ 'TXT' 它会运行:

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

这运行得非常缓慢,解释表明它正在扫描所有记录而不是使用我的索引 . 如果我手动运行:

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

它使用索引并运行得更快 . 在这种情况下,似乎我不想使用ElemMatch,但MongoDB Builder命名空间似乎不适合这种类型的查询,例如

Query.EQ("MetaData", expression);

在语法上是不正确的 . 我已经倾倒了文档甚至MongoDB驱动程序源代码,但无法找到如何做我想要的 . 我错过了一些明显的东西吗

1 回答

  • 1

    EQ 方法仅接受 BSONValue 作为参数,但您尝试传递 IMongoQuery 实例 .

    在第二个查询中,您基本上是在 MetaData 数组中搜索此文档:

    {"FileExtension":"TXT"}
    

    您需要创建一个新的BsonDocument并将其传递给 EQ 方法:

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

    您可以查看documentation for EQ method了解更多详情 .

相关问题