MongoDb逻辑查询运算符和大括号

时间:2017-07-06 14:50:16

标签: mongodb aggregation-framework

在运行聚合查询时,在mongoDB中嵌套和使用逻辑运算符时使用大括号的规则是什么规则有些查询有效,而其他查询没有,如下所示?

  

方案1(有效):

scenario 2 (works):

$project:
{
 $and:[{"data":"Residential"},{"status":true}],                                                                                       
}
$and:
[
 {
  $and:[{"data":"Residential"},{"status":true}],                                                                                          
  $and:[{"data":"Lobby"},{"status":true}],                                                                                                                            
 }
]
  

方案3(有效)

$and:
[
  {
    $and:[{"data":"Residential"},{"status":true}],    
  },
  {                                                                                       
    $and:[{"data":"Lobby"},{"status":true}],                                                                                                                          
  }
]
  

方案3(将给出方案2结果的不同结果)

$and:[
  {
    $or:[
         {
          $and:[
                 {"data":"Kids"},
                 {"status":true}
               ]  
         },
        {                                         
         $and:[                       
                 {"data":"Adults"},
                 {"status":true}                                                                                                  
             ]                                        
         }
       ]
      }                                                                                                                               
]

方案4(有效):

$and:[
{                                          
 $or:
 [
  {
    $and:[{"data":"Kids"},{“status":true} ].                                        
    $and:[{"data":"Adults"},{"status":true} ]                                   
  }
 ]
}
],

如果我这样做,情景4会给出不同的结果:

static void Main(string[] args)
{
    WriteQueryResultsToCsv(@"c:\SqlResults.csv", 
        "MyDbConnectionStringName", 
        "select * from MyTable where x > @x",
        new SqlParameter("@x", SqlDbType.Int) {Value = 1});
}

private static void WriteQueryResultsToCsv(string csvPath, string connectionStringName, string sql, params SqlParameter[] parameters)
{
    // Requires reference to System.Configuration
    var connectionString = ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString;

    using (var db = new SqlConnection(connectionString))
    using (var cmd = new SqlCommand(sql, db))
    {
        db.Open();
        cmd.Parameters.AddRange(parameters);

        using (var dr = cmd.ExecuteReader())
        using (var dw = new StreamWriter(csvPath))
        using (var csv = new CsvWriter(dw)) // Requires CsvHelper package from NuGet
        {
            // Write column headers
            for (var c = 0; c < dr.FieldCount; c++)
                csv.WriteField(dr.GetName(c));

            // Write data rows
            while (dr.Read())
            {
                csv.NextRecord();
                for (var c = 0; c < dr.FieldCount; c++)
                {
                    csv.WriteField(dr.GetValue(c).ToString());
                }
            }
        }
    }
}

此类详细信息未在文档中指出。

1 个答案:

答案 0 :(得分:0)

所以我已经意识到的一件事是,带有$和或$的嵌套大括号可以被视为一个单独的步骤/阶段,具体取决于我们如何使用它们。此概念称为 Coalescence ,并在聚合管道优化(https://docs.mongodb.com/manual/core/aggregation-pipeline-optimization/#match-match-coalescence)下详细讨论。 让我用一个例子解释一下。

假设我们有x = [1,2,3,5,8,13,21,34,55];我们想在我们的聚合中过滤掉它。案例一。 我先做了一个大于,然后小于一个原因的比较。

$project:
 {
  $and: [ { $gt: [ "$qty", 25 ] },{ $lt: [ "$qty", 5 ] }]
 }
  

我们应该得到8,13,21

的结果

接下来让我们尝试一下

$ project:

$and:
[
 {
  $and:[{ $gt: [ "$qty", 25 ] }],                                                                                          
  $and:[{ $lt: [ "$qty", 5 ] }],                                                                                                                            
 }
]
  

我们应该得到8,13,21的结果,因为它一下子就去了

最后一个例子

$and:
[
  {
    $and:[{ $gt: [ "$qty", 25 ] }],    
  },
  {                                                                                       
    $and:[{ $lt: [ "$qty", 5 ] }],                                                                                                                              
  }
]
  

我们应该得到[]或空的结果。

我们将获得一个空列表的原因是我们将分两个阶段运行上述查询。对于大于25的数字,第一阶段将过滤我们的值 x ,它将返回一个新列表。然后,下一阶段将继续过滤我们的第一阶段的结果,对于小于5的数字,这将是空的,因为结果集只包含大于25的数字。

所以这里的教训是,如果你在$和$内部查询了嵌套部分,或者被告知每个大括号都被视为一个单独的阶段,后面的阶段会对前一阶段的结果起作用。