如何在 MongoDB 查询中将 $elemMatch 与 $nin 或 $not 结合起来?

pul*_*hal 0 mongodb mongodb-query

我想找到数组 fieldB 在 fieldC 对象中没有值(val1 和 val2)的所有结果。

我努力了:

db.SalesToImport
  .find(
    {
      fieldA: {$exists:true},
      ,fieldB: {$not: {$elemMatch: {fieldC: 'val1'}}}
      ,fieldB: {$not: {$elemMatch: {fieldC: 'val2'}}}
    }
  );
Run Code Online (Sandbox Code Playgroud)

我已经尝试过:

db.SalesToImport
  .find(
    {
      fieldA: {$exists:true},
      ,fieldB: {$not: {$elemMatch: {fieldC: 'val1', fieldC: 'val2'}}}
    }
  );
Run Code Online (Sandbox Code Playgroud)

它们都产生相同的结果,虽然它们删除了一些文档,但其中仍然有文档val1val2这告诉我我做了一个不正确的查询。

文档的结构包含如下字段:

{
  fieldA: value,
  fieldB: [
    {fieldC:value1, fieldD:value3, fieldE:value5},
    {fieldC:value2, fieldD:value4, fieldE:value6}
  ]
}
Run Code Online (Sandbox Code Playgroud)

我应该如何在 MongoDB 查询中将 $elemMatch 与 $nin 或 $not 结合起来以获得所需的效果?

更新#1

根据建议,我运行了以下实际但经过清理的查询:

db.SalesToImport
  .find(
    {
      calculatedTaxRate: {$exists:true}, unidentifiedProducts: {$exists:false}, unidentifiedCustomer: {$exists:false},
      register_sale_payments: {
        $elemMatch: {
          retailer_payment_type_id : {
            $nin: [
              '0af7b240-ab24-11e7-eddc-9fff6de134e9'
              ,'0af7b240-ab24-11e7-eddc-9fff69293826'
            ]
          }, 
        }
      }
    },
    {_id:0,status:0,customer_id:0,register_id:0}
  )
  .sort({"calculatedTaxRate":1});
Run Code Online (Sandbox Code Playgroud)

但响应仍然在fieldB.fieldC或中产生不需要的结果register_sale_payments.retailer_payment_type_id,所以这不是我想要的或者我在使用它时犯了错误。

更新#2

根据建议,我运行了以下实际但经过清理的查询:

db.SalesToImport
  .find(
    {
      calculatedTaxRate: {$exists:true}, unidentifiedProducts: {$exists:false}, unidentifiedCustomer: {$exists:false},
      'register_sale_payments.retailer_payment_type_id': {
        $nin: [
          '0af7b240-ab24-11e7-eddc-9fff6de134e9'
          ,'0af7b240-ab24-11e7-eddc-9fff69293826'
        ]
      }
    },
    {_id:0,status:0,customer_id:0,register_id:0}
  )
  .sort({"calculatedTaxRate":1});
Run Code Online (Sandbox Code Playgroud)

成功了!

bar*_*ini 5

虽然您只对 的一个领域感兴趣fieldB,但您不需要使用$elemmatch.

db.SalesToImport.find(
{
  "fieldA": {$exists:true},
  "fieldB.fieldC": { $nin: ["val1", "va2"] }
}
);
Run Code Online (Sandbox Code Playgroud)

fieldB例如,如果您有一个 fieldD ,您不希望 fieldD 也有值 val3、val4 :

db.SalesToImport.find(
{
  "fieldA": { $exists: true },
  "fieldB.fieldC": { $nin: ["val1", "va2"] },
  "fieldB.fieldD": { $nin: ["val3", "va4"] }
}
);
Run Code Online (Sandbox Code Playgroud)

上面的查询也排除了 fieldC、fieldD 对的文档:(val5, val3),因为我们分别查询 fieldC 和 fieldD。

如果要查询fieldBfieldC 和 fieldD 没有值对 (val1, val3), (val1, val4), (val2, val3), (val2, val4) :

db.SalesToImport.find(
{
  "fieldA": { $exists: true },
  "fieldB": { $elemmatch: {
    "fieldC" : { $nin: ["val1", "val2"] }, 
    "fieldD": { $nin: ["val3", "val4"] } } 
   }
}
);
Run Code Online (Sandbox Code Playgroud)

上面的查询不排除filedC,fieldD对,例如:(val5,val3)