Агрегировать данные из вложенного массива - PullRequest
0 голосов
/ 20 мая 2019

Мне нужна помощь с агрегатной структурой. У меня есть модель (поле валют может содержать более одного объекта):

const schema = new mongoose.Schema({
  country: { type: String },
  code: { type: String },
  region: [{
    name: { type: String },
    path: { type: Array },
    city: [{
      name: { type: String },
      path: { type: Array },
      latitude: { type: String },
      longitude: { type: String },
    }],
  }],
  currencies: [{
    code: { type: String },
    name: { type: String },
    symbol: { type: String },
  }],
})

И мне нужно получать все валюты без дубликатов. Полученные данные можно посмотреть так:

[
  { code: 'string', name: 'sting', symbol: 'string' },
  { code: 'string', name: 'sting', symbol: 'string' },
  ...
]
// or like this:
[
  currencies: [
    { code: 'string', name: 'sting', symbol: 'string' },
    { code: 'string', name: 'sting', symbol: 'string' },
    ...
  ]
]

Я пытаюсь создать запрос

Geo.aggregate([
  {
    $group: {
       _id: null,
       currencies: { $addToSet: '$currencies' },
    },
  },
])

но получите эти данные с дубликатами, и у них есть много вложенных массивов:

[
  {
    "_id": null,
    "currencies": [
      [
        {
          "_id": "5cd9486248989616a411fac5",
          "code": "JPY",
          "name": "Japanese yen",
          "symbol": "¥"
        }
      ],
      [
        {
          "_id": "5cd9491a48989616a411fb47",
          "code": "TRY",
          "name": "Turkish lira",
          "symbol": null
        }
      ],

Я пробую этот запрос:

Geo.aggregate([
  {
    $addFields: {
      code: '$currencies.code',
      name: '$currencies.name',
      symbol: '$currencies.symbol',
    },
  },
])

Но я получаю сообщение об ошибке «Ошибка типа: элемент не повторяется». Мне нужна небольшая помощь)

Просмотр данных в БД:

{
    "_id": {
        "$oid": "5c3334a8871695568817eadf"
    },
    "country": "Singapore",
    "code": "sg",
    "region": [
        {
            "path": [
                "Singapore"
            ],
            "_id": {
                "$oid": "5c3366c63d92ac6e531e05c0"
            },
            "city": [],
            "name": "Central Singapore Community Development Council"
        },
        ....
    ],
    "__v": 0,
    "currencies": [
        {
            "_id": {
                "$oid": "5cd948ec48989616a411fb28"
            },
            "code": "BND",
            "name": "Brunei dollar",
            "symbol": "$"
        },
        {
            "_id": {
                "$oid": "5cd948ec48989616a411fb27"
            },
            "code": "SGD",
            "name": "Singapore dollar",
            "symbol": "$"
        }
    ]
}

Ответы [ 2 ]

1 голос
/ 20 мая 2019

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

Geo.aggregate([
 {
   $unwind: '$currencies'
 },
 {
     $group: {
     _id: null,
     currencies: { $addToSet: '$currencies' },
    },
 },
])

Для получения дополнительной информации вы можете посмотреть документацию здесь

0 голосов
/ 20 мая 2019
db.temp.aggregate([
   {$project : {currencies : 1}}, 
   {$unwind: "$currencies"}, 
   {
      $addFields: {
         currencyHash: {
            $concat : ['$currencies.code', "--", "$currencies.name", "--", "$currencies.symbol"]
         }
      }
   },
   {
      $group: {
         _id: "$currencyHash",
         currency : {
            $first : "$currencies"
         }
      }
   },
   {
       $project: {
          code : "$currency.code",
          name : "$currency.name",
          symbol : "$currency.symbol"
       }
   },
   {
       $project: {
          _id : 0,
          currency : 0
       }
   }
]).pretty()
...