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控制台中工作):

第一个查询按预期使用索引。第二种情况并非如此

问题摘要

  • 这两个find()查询是否等效
  • 如果是,为什么他们的行为不同?如果没有,它们有何不同
  • 如何在没有$的情况下使用C#驱动程序生成find()
  • 编辑--------

    记录在案,我在C#中使用的语法大致如下:

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