Получение размера массива в условии без использования $ match - PullRequest
0 голосов
/ 20 февраля 2019

У меня есть запрос, который мне нужно написать, где мне нужно определить количество элементов в массиве (я знаю, что это можно сделать через $project с $size, а затем $match), но затем мне нужнобыть в состоянии обработать элементы массива, которые соответствуют этому условию, и если они не удовлетворяют условию, оставьте их.Я не хочу исключать элементы, которые не соответствуют критериям, через $match

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

db.collection.aggregate([
  { $project: { _id:1,  
                themeArraySize: { $gt: [ {$size: "$themes" }, 1 ] } } },
  { $match: { themeArraySize : true }} ,
])

Мне нужно обернуть это в условие, а не исключать что-либо путем сопоставления

«Логика» того, чего я хочу достичь для массива тем, такова:

  1. Если массив имеет длину> 1 И
  2. Есть элемент массива со значением "[]" ИЛИ "НЕ ВЫБРАНЫ ТЕМЫ"
  3. THEN $ PULL«[]» или «НЕТ ВЫБРАННЫХ ТЕМ» из массива тем
  4. В противном случае возвращает themes массив

Часть, с которой я борюсь, - это как обрабатывать истинулогика

Помещение в предложение:

"Если в массиве есть тема '[]', и это единственная тема, оставьте ее в покое. Но если'[]' присутствует, и есть другие темы, удалите '[]' из массива "

Я начал:

{
            "$project": {
              "conversationid": 1,
              "themes": {
                "$cond": [
                  {
                    "$and": [
                      {
                        "$or": [
                          {
                            "$in": [
                              "[]",
                              "$themes"
                            ]
                          },
                          {
                            "$in": [
                              "NO THEMES SELECTED",
                              "$themes"
                            ]
                          }
                        ]
                      },
                      {
                        "$themes": {
                          "$gte": [
******I WANT TO SAY THAT THE THEMES ARRAY MUST BE >1 IN SIZE HERE******
                          ]
                        }
                      }
                    ]
                  },
                  {
                    "$pull": {
                      "$themes": {
                        "$in": [
                          "NO THEMES SELECTED",
                          "[]"
                        ]
                      }
                    }
                  },
                  "$themes"
                ]
              }
            }
          },

Но я получаюСмысл в том, что то, что я хочу сделать, невозможно

Спасибо

Ответы [ 2 ]

0 голосов
/ 20 февраля 2019

Весь кредит и большое спасибо @mickl.Мне пришлось внести небольшие изменения в их ответ, так как раньше я получал сообщение об ошибке «Аргумент $ size должен быть массивом, но имел тип: пропущен»

Для борьбы с этим я добавил этап проекта впосчитать количество элементов в массиве, затем добавил соответствие, чтобы убедиться, что число больше 0. Это означало, что я могу только передать массив в решение @ mickl

Полный код:

{
    "$project": {
        "item": 1,
        "themes": 1,
        "conversationid": 1,
        "numberOfItemsInArray": {
            "$cond": {
                "if": {
                    "$isArray": "$themes"
                },
                "then": {
                    "$size": "$themes"
                },
                "else": 0
            }
        }
    }
},
{
    "$match": {
        "numberOfItemsInArray": {
            "$gt": 0
        }
    }
},
{
    "$addFields": {
        "themes": {
            "$cond": [
                {
                    "$eq": [
                        {
                            "$size": "$themes"
                        },
                        1
                    ]
                },
                "$themes",
                {
                    "$filter": {
                        "input": "$themes",
                        "cond": {
                            "$and": [
                                {
                                    "$ne": [
                                        "$$this",
                                        "[]"
                                    ]
                                },
                                {
                                    "$ne": [
                                        "$$this",
                                        "NO THEMES SELECTED"
                                    ]
                                }
                            ]
                        }
                    }
                }
            ]
        }
    }
},
{
    "$unwind": "$themes"
},
0 голосов
/ 20 февраля 2019

Вы можете использовать $ addFields для замены существующего поля themes, $ cond для определения вашей логики и $ filter для удаления некоторых определенных элементов из themes массив, попробуйте:

db.collection.aggregate([
    {
        $addFields: {
            themes: {
                $cond: [
                    { $eq: [ { $size: "$themes"} , 1 ] },
                    "$themes",
                    {
                        $filter: {
                            input: "$themes",
                            cond: {
                                $and: [
                                    { $ne: [ "$$this", "[]" ] },
                                    { $ne: [ "$$this", "NO THEMES SELECTED" ] }
                                ]
                            }
                        }
                    }
                ]
            }
        }
    }
])

для следующих данных:

db.collection.save({ themes: [ "something" ] })
db.collection.save({ themes: [ "[]" ] })
db.collection.save({ themes: [ "NO THEMES SELECTED" ] })
db.collection.save({ themes: [ "Something else", "NO THEMES SELECTED" ] })
db.collection.save({ themes: [ "Something else (2)", "[]" ] })

возвращает:

{ "_id" : ObjectId("5c6d75246fb49f04a0a1f6a6"), "themes" : [ "something" ] }
{ "_id" : ObjectId("5c6d75246fb49f04a0a1f6a7"), "themes" : [ "[]" ] }
{ "_id" : ObjectId("5c6d75246fb49f04a0a1f6a8"), "themes" : [ "NO THEMES SELECTED" ] }
{ "_id" : ObjectId("5c6d75246fb49f04a0a1f6a9"), "themes" : [ "Something else" ] }
{ "_id" : ObjectId("5c6d75246fb49f04a0a1f6aa"), "themes" : [ "Something else (2)" ] }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...