C# Mongo显式/隐式和行为不同
基本问题: 以下两个查询是否等效C# Mongo显式/隐式和行为不同,c#,mongodb,indexing,mongodb-indexes,C#,Mongodb,Indexing,Mongodb Indexes,基本问题: 以下两个查询是否等效 (A) coll.find(k1:v1, k2:v2) // List of fields (B) coll.find($and: [{k1:v1}, {k2:v2}]) // $and the list of fields 如果是,为什么他们表现出不同的行为?(见下文)。如果不是,如何在C#中生成前者 进一步讨论 我正在为子文档中的字段编制索引。查询(A)正确使用索引,但查询(B)不正确 以下是一些示例代码(它将直接在mongo控制台
(A) coll.find(k1:v1, k2:v2) // List of fields
(B) coll.find($and: [{k1:v1}, {k2:v2}]) // $and the list of fields
如果是,为什么他们表现出不同的行为?(见下文)。如果不是,如何在C#中生成前者
进一步讨论
我正在为子文档中的字段编制索引。查询(A)正确使用索引,但查询(B)不正确
以下是一些示例代码(它将直接在mongo控制台中工作):
第一个查询按预期使用索引。第二种情况并非如此
问题摘要
coll.find(Query.And([<id query>, <fields query>]));
coll.find(Query.And([,]);
手动生成QueryDocument不起作用,因为它不能包含多个$或作为$的查询,或用作字典的键(我需要多个$或在实际查询中).我已经确定,当mongo文档声明它提供了一个隐式的操作列表,并且指定了一个逗号分隔的操作列表时,它有点误导。以下面的查询为例:
// Returns 19 documents on sample data.
coll.find({{a simple query}, {an $or query}, {another $or query}})
在上述情况下,我发现$or查询之一可能会被忽略。也就是说,这3个查询没有与$and组合。提供明确的$,并修复此问题:
// Returns 2 documents on the same sample data.
coll.find({$and: [{a simple query}, {an $or query}, {another $or query}]})
是的,这两个查询在功能上是等价的 关于执行此查询
db.test.find({
_id:{$lt:20},
“$or”:[{“Fields.K1”:123},{“Fields.K2”:123}]
})
使用C#驱动程序,您可以通过以下方式实现:
var query = Query.And(Query.LT("_id", 20),
Query.Or(Query.EQ("Fields.K1", 123),
Query.EQ("Fields.K2", 123)));
var docs = test.Find(query);
即使使用了Query.And
,如果检查调用Query.ToJson()
的输出,也会生成一个隐式And查询:
{“\u id”:{“$lt”:20},“$or”:[{“Fields.K1”:123},{“Fields.K2”:123}]
与原始查询匹配的
至于为什么一些显式的
$和查询不使用索引(或者在本例中使用不同的索引),而等价的隐式和查询使用索引,Mongo将显式和隐式转换为隐式的内部能力似乎并不完美,这就是为什么您只想在必要时使用$和
。来自文档:MongoDB在指定以逗号分隔的表达式列表时提供隐式AND操作
还要检查:如果是这种情况,为什么显性和隐性的行为不同于隐性和隐性的行为?关于在没有显式C#驱动程序的情况下生成查询的问题仍然存在。我目前正在执行coll.find(Query.And([,])。这不正确。对于隐式AND查询,您不会将多个对象传递给coll.find
,而是传递一个对象,其中包含多个字段,这些字段表示多个AND组合在一起的术语。谢谢,已编辑。我不是想让它显示为一个单独查询的列表。这是一个包含子查询的单一查询。我在C#中运行了一些测试,在这一点上同意您的看法。我被解雇了,因为C#driver似乎生成了一个明确的$and,在某些情况下,而不是在其他情况下,我错过了后一种情况。但是,您能解释一下原始问题中.explain()对两个查询的行为为何不同吗?那么这个答案将是正确的。@mmmdreg请参阅更新的答案。简言之,只有在必要时才使用$和
,这样您就不会依赖Mongo来确定它是否可以转换为隐式and.Thank。从mongo 2.5.3开始,由于最近的查询框架增强,似乎已经纠正了不一致的行为。看见
var query = Query.And(Query.LT("_id", 20),
Query.Or(Query.EQ("Fields.K1", 123),
Query.EQ("Fields.K2", 123)));
var docs = test.Find(query);