Как сопоставить только документы, в которых условие, включающее другой массив, применяется ко всем документам в массиве? - PullRequest
0 голосов
/ 23 октября 2019

Есть много вопросов / ответов, звучащих точно так же, как я ищу, но я не смог найти ни одного, который действительно работал бы для меня.

Пример данных:

{
  "_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 не существует или содержит только документы, у которых нет действительной даты shipmentDate.

В настоящее время у меня естьthis (используя pymongo):

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

Но, конечно, это не учитывает, что все документы внутри LinVw.orderResponses должны соответствовать условию.

Большинство наших примеров не касаются такого рода вложений, и я не смог их переписать соответственно.

Буду признателен за любую помощь.

Ответы [ 2 ]

0 голосов
/ 23 октября 2019

Я думаю, что сделал это:

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}}
])
0 голосов
/ 23 октября 2019

Этого можно добиться, добавив этап $ redact .

На этапе $redact вы записываете документы, соответствующие запросу, которые вы хотите игнорировать (с недопустимой датой shipMent). Вот и все.

...