Сделайте Pymon go Запрос с Elemmatch и фильтром - PullRequest
0 голосов
/ 02 апреля 2020

У меня следующая структура данных:

[
    {
        "site_id": ObjectId("5e85b9d20498abd407e9a030"),
        "status": "ERROR"
    },
    {
        "site_id": ObjectId("5e85b9d20498abd407e9a120"),
        "status": "ERROR"
    },
    {
        "site_id": ObjectId("5e85b9d20498abd407e9a030"),
        "status": "OK",
        "risk_categories": [
            {

                "position": 1,
                "category_id": 1414,
            },
            {

                "position": 2,
                "category_id": 1402,

            },
            {

                "position": 3,
                "category_id": 1392,

            }
                ]
    }
]

Я хочу сделать запрос с помощью pymon go, например так:

collection.find_one (filter = filter)

где: filter = {'$ and': [{'$ and': [{'site_id': ObjectId ('5e85b9d20498abd407e9a030')}, {'status': 'OK'}]}, {'risk_categories' : {'$ elemMatch': {'$ or': [{'position': {'$ eq': 1}}, {'position': {'$ eq': 2}}]}}}]}

однако он возвращает мне весь объект. Не только значения категорий риска, которые я хочу. Что я могу сделать на своем фильтре, чтобы изменить это?

1 Ответ

2 голосов
/ 02 апреля 2020

Агрегация запускается из mongo shell:

db.collection.aggregate( [
  { 
      $match:  { 
          site_id: ObjectId('5e85b9d20498abd407e9a030'), 
          status: "OK" 
      } 
  },
  { 
      $addFields: {
          risk_categories: { 
              $filter: { 
                  input: "$risk_categories", 
                  as: "cat",
                  cond: {
                      $in: [ "$$cat.position", [ 1, 2 ] ]    // this is equivalent to using the "$or"
                  }
              }
          }
      }
  },
] ).pretty()

Вывод:

{
        "_id" : ObjectId("5e85c7b6724e461876467077"),
        "site_id" : ObjectId("5e85b9d20498abd407e9a030"),
        "status" : "OK",
        "risk_categories" : [
                {
                        "position" : 1,
                        "category_id" : 1414
                },
                {
                        "position" : 2,
                        "category_id" : 1402
                }
        ]
}



Использование PyMon go 3.9 и MongoDB 4.2 из оболочки Python:

import pymongo
from pymongo import MongoClient
client = MongoClient()
db = client.test
collection = db.collection
import pprint
from bson.objectid import ObjectId

pipeline = [
  { 
      '$match':  { 
          'site_id': ObjectId('5e85b9d20498abd407e9a030'), 
          'status': 'OK'
      } 
  },
  { 
      '$addFields': {
          'risk_categories': { 
              '$filter': { 
                  'input': '$risk_categories', 
                  'as': 'cat',
                  'cond': {
                      '$in': [ '$$cat.position', [ 1, 2 ] ]
                  }
              }
          }
      }
  },
]

pprint.pprint(list(collection.aggregate(pipeline)))
...