遵循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驱动程序源代码,但无法找到如何做我想要的。我错过了一些明显的东西吗
答案 0 :(得分:1)
EQ
方法仅接受BSONValue
作为参数,但您尝试传递IMongoQuery
个实例。
在您的第二个查询中,您基本上在MetaData
数组中搜索此文档:
{"FileExtension":"TXT"}
您需要创建一个新的BsonDocument并将其传递到您的EQ
方法中:
Query.EQ("MetaData", new BsonDocument(leaf.Field, leaf.Value));
您可以查看documentation for EQ method了解详情。