【问题标题】:How to match only documents where a condition, that includes another array, applies to all documents in an array?如何仅匹配包含另一个数组的条件适用于数组中所有文档的文档?
【发布时间】:2019-10-23 10:05:53
【问题描述】:

有很多问题/答案听起来与我正在寻找的完全一样,但我找不到一个真正适合我的问题/答案。

样本数据:

{
  "_id": "5daeb61790183fd4d4361d6c",
  "orderMessageId": "7563_21",
  "orderId": "OS00154",
  "orderEntryDate": "2019-06-17T00:00:00.000Z",
  "typeOfOrder": "ORD",
  "express": false,
  "name1": "xxx",
  "name2": "xxx",
  "name3": " ",
  "contact": "IN KOMMISSION",
  "street": "xxx",
  "city": "xxx",
  "zipcode": "1235",
  "country": "xx",
  "customerId": "51515",
  "lnatMarketCode": "Corporate - Regulatory",
  "shipmentCarrier": "ABH",
  "typeOfShipment": "83",
  "typeOfShipmentDescr": "xxx",
  "orderTextfield": " ",
  "orderTextfield02": " ",
  "text2": " ",
  "LinVw": [
    {
      "orderLineMessageId": "OS05451",
      "orderLineId": 5,
      "articleId": "19200",
      "articleDescription": "xxx",
      "productId": "OS1902",
      "productDescription": "xxx",
      "baseQuantityUnit": "EA",
      "quantityOrdered": 2,
      "isbn": "978357468",
      "issn": " ",
      "orderSubmissionDate": "2019-06-06T00:00:00.000Z",
      "customerPurchaseOrderId": "728188175",
      "lnatCustomerIdAtSupplier": " ",
      "supplierDeliveryNoteId": " ",
      "fulfillmentContactName": "xxxx",
      "customerVatRegistrationCode": "AT4151511900",
      "listPriceInclVat": 21.4955,
      "text": " ",
      "orderResponses": [
        {
          "orderMessageId": "7718677_1",
          "orderLineMessageId": "OS0000015451",
          "orderId": "OS000154",
          "orderLineId": 5,
          "articleId": "1911200",
          "quantity": 2,
          "quantityNotShipped": 0,
          "reasonForNotShippedCode": null,
          "reasonForNotShipped": null,
          "shipmentDate": "2019-10-04T00:00:00.000Z",
          "deliveryNoteId": null,
          "trackingIds": [
            {
              "trackingId": null,
              "quantityRefToTracking": "2",
              "weightRefToTracking": "0.0"
            }
          ],
          "type": "orderresponse",
          "filepath": "xxxORDERRESP_20191004131209.xml",
          "_id": "OS005451"
        },
        {
          "orderMessageId": "753_21",
          "orderLineMessageId": "OS015451",
          "orderId": "O00154",
          "orderLineId": 5,
          "articleId": "100200",
          "quantity": 0,
          "quantityNotShipped": 2,
          "reasonForNotShippedCode": "01",
          "reasonForNotShipped": "Out of Stock",
          "shipmentDate": null,
          "deliveryNoteId": null,
          "trackingIds": [
            {
              "trackingId": null,
              "quantityRefToTracking": "0",
              "weightRefToTracking": "0.0"
            }
          ],
          "type": "orderresponse",
          "filepath": "xxxxORDERRESP_20190618161529.xml",
          "_id": "OS0000015451"
        }
      ]
    }
  ],
  "filepath": "xxxxxORDER_7539563_20190618_071522.xml"
}

我要匹配所有文档,其中所有文档在数组LinVw中,匹配如下条件:

{'$or': [{'LinVw.orderResponses': {'$exists': False}}, {'LinVw.orderResponses.shipmentDate': {'$type': 10}}]}

换句话说:我想匹配文档,如果数组 LinVw.orderResponses 不存在,或者它只包含文档,并且没有有效的 shippingDate。

目前我有这个(使用 pymongo):

result = order_collection.aggregate([
{"$unwind": "$LinVw"},
{"$match": {'$or': [{'LinVw.orderResponses': {'$exists': False}}, {'LinVw.orderResponses.shipmentDate': {'$type': 10}}]}}
])

但这当然并不认为 LinVw.orderResponses 中的所有文档都应该符合条件。

我们那里的大多数示例都没有处理这种嵌套,我无法相应地重写它们。

我将不胜感激。

【问题讨论】:

  • 你能客观解释一下吗?
  • @niranjanharpale 对不起,我没有关注。你要我解释什么?

标签: mongodb mongodb-query aggregation-framework


【解决方案1】:

您可以通过添加$redact 阶段来实现此目的。

$redact 阶段,您写下要忽略的查询匹配文档(具有无效的发货日期)。就是这样。

【讨论】:

  • @pypat 我会为您编写完整的查询,但您的示例文档格式不正确(缺少右括号)。希望这可以帮助。如果您在实施它时遇到任何困难,请告诉我。如果此答案对您有帮助,请点赞或接受答案。
  • 谢谢,但我觉得我遇到了同样的问题。至少结果是一样的。这是我的编辑阶段: {"$redact": {"$cond": [{"$not":[{'shipmentDate': None}]}, "$$PRUNE", "$$KEEP"]}}
  • @pypat 我可以向你保证,它可以使用 $redact 来完成。如果您可以简单地格式化您的示例文档并共享示例结果,我会更容易回答。确保通过插入 db 来测试您的示例文档,如果它没有给出任何错误,我可以在我的系统上编写和测试它。
  • 我确实在我的操作中修复了 python dict,它现在可以插入了。
  • 不。错误太多E QUERY [thread1] ReferenceError: False is not defined E QUERY [thread1] ReferenceError: None is not defined等等
【解决方案2】:

我想我做到了:

result = order_collection.aggregate([
{"$unwind": "$LinVw"},
{"$match": {'$or': [{'LinVw.orderResponses': {'$exists': False}}, {'LinVw.orderResponses.shipmentDate': {'$type': 10}}]}},
{"$match": {'LinVw.orderResponses.shipmentDate': {"$not":{'$type': 9}}}},
{"$project":{"_id":0, "LinVw.orderLineMessageId":1, "LinVw.orderResponses":1}}
])

【讨论】:

  • @invider 也许你可以验证这是否有意义?
猜你喜欢
  • 2017-03-20
  • 2015-12-15
  • 1970-01-01
  • 2016-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-21
  • 2022-01-22
相关资源
最近更新 更多