Пн go Запрос на выборку отдельных вложенных документов - PullRequest
6 голосов
/ 13 июля 2020

Мне нужно получить отдельные вложенные документы.

Найдите образец документа:

{
    "propertyId": 1001820437,
    "date": ISODate("2020-07-17T00:00:00.000Z"),
    "HList":[
        {
            "productId": 123,
            "name": "Dubai",
            "tsh": true
        }
    ],
    "PList":[
        {
            "productId": 123,
            "name": "Dubai",
            "tsh": false
        },
        {
            "productId": 234,
            "name": "India",
            "tsh": true
        }
    ],
    "CList":[
        {
            "productId": 234,
            "name": "India",
            "tsh": false
        }
    ]
}

Ожидаемый результат:

{
    "produts":[
        {
            "productId": 123,
            "name": "Dubai"
        },
        {
            "productId": 234,
            "name": "India"
        }
    ]
}

Я попытался выполнить этот запрос :

 db.property.aggregate([
    { 
        $match: { 
            "propertyId": 1001820437,
            "date": ISODate("2020-07-17T00:00:00.000Z")
        }
    },
    { 
        "$project": {
            "_id": 0,
            "unique": {
                "$filter": {    
                    "input": {
                        "$setDifference": [
                            { 
                                "$concatArrays": [
                                    "$HList.productId",
                                    "$PList.productId",
                                    "$CList.productId"
                                ]
                            },
                            []
                        ]  
                    },
                    "cond": { 
                        "$ne": [ "$$this", "" ] 
                    }
                }
            }
        }
    }
]);

Правильно ли здесь агрегирование $setDifference? Мой запрос возвращает только уникальные идентификаторы продуктов, но мне нужен productId с name. Может ли кто-нибудь помочь мне решить эту проблему? Заранее спасибо

Ответы [ 3 ]

5 голосов
/ 19 июля 2020

Вы можете сначала использовать $project, чтобы избавиться от поля tsh, а затем запустить $ setUnion , который игнорирует повторяющиеся записи:

db.collection.aggregate([
    {
        $project: {
            "HList.tsh": 0,
            "PList.tsh": 0,
            "CList.tsh": 0,
        }
    },
    {
        $project: {
            products: {
                $setUnion: [ "$HList", "$PList", "$CList" ]
            }
        }
    }
])

Mon go Детская площадка

3 голосов
/ 20 июля 2020

Следующие две агрегации возвращают ожидаемый и тот же результат (вы можете использовать любой из двух):

db.collection.aggregate( [
  { 
      $project: { 
          _id: 0, 
          products: {
              $reduce: {
                  input: { $setUnion: [ "$HList", "$PList", "$CList" ] }, 
                  initialValue: [],
                  in: {
                      $setUnion: [ "$$value", [ { productId: "$$this.productId", name: "$$this.name" } ] ]
                  }
              } 
          } 
      } 
  }
] )

Это немного многословно:

db.collection.aggregate( [
  { 
      $project: { list: { $setUnion: [ "$HList", "$PList", "$CList" ] } } 
  },
 { 
      $unwind: "$list" 
  },
  { 
      $group: { 
          _id: null, 
          products: { $addToSet: { "productId": "$list.productId", "name": "$list.name" } } 
      } 
  },
  { 
      $project: { _id: 0 } 
  }
] )
0 голосов
/ 30 августа 2020
db.collection.aggregate([
   { 
      $match: { 
               "propertyId": 1001820437,
               "date": ISODate("2020-07-17T00:00:00.000Z")
    
               }
    },
    {
        $project: {
            products: {
                $filter: {
                 input: { "$setUnion" : ["$CList", "$HList", "$PList"] },
                 as: 'product',
                 cond: {}
                 }
            }
         }
    },
    {
       $project: {            
                   "_id":0,
                   "products.tsh": 1,
                   "products.name": 1,           
                 }
    }, 
])
...