Невозможно использовать Nested VariableOperators.mapItemsOf в Spring Data MongoDb - PullRequest
0 голосов
/ 25 сентября 2018

Я вынужден использовать структуру агрегации и проект операцию Spring Data MongoDb .

Что бы я хотелсделать, это создать массив объекта в результате операции проекта.

Учитывая этот промежуточный результат агрегации:

{
  "processes": [
    {
      "id": "101a",
      "assignees": [
        {
          "id": "201a",
          "username": "carl93"
        },
        {
          "id": "202a",
          "username": "susan"
        }
      ]
    },
    {
      "id": "101b",
      "assignees": [
        {
          "id": "201a",
          "username": "carl93"
        },
        {
          "id": "202a",
          "username": "susan"
        }
      ]
    }
  ]
}

Я пытаюсь получить для каждого процесса, все получательимена пользователей и идентификаторы.Следовательно, я хочу получить что-то вроде этого:

[
  {
    "results": [
      {
        "id": "201a",
        "value": "carl93",
        "parentObjectId": "101a"
      },
      {
        "id": "202a",
        "value": "susan",
        "parentObjectId": "101a"
      },
      {
        "id": "201a",
        "value": "carl93",
        "parentObjectId": "101b"
      },
      {
        "id": "202a",
        "value": "susan",
        "parentObjectId": "101b"
      }
    ]
  }
]

Для достижения этой цели я использую 2 вложенных VariableOperators.mapItemsOf для получения:

org.springframework.data.mapping.MappingException: Cannot convert [Document{{id= 201a, value= carl93, parentObjectId= 101a}}, Document{{id= 202a, value = susan, parentObjectId= 101a}}]
of type class java.util.ArrayList into an instance of class java.lang.Object! 
Implement a custom Converter<class java.util.ArrayList, class java.lang.Object> and register it with the CustomConversions.

Вот код, который яВ настоящее время использую:

new ProjectionOperation().and(
    VariableOperators.mapItemsOf("processes")
      .as("pr")
      .andApply(
           VariableOperators.mapItemsOf("$pr.ownership.assignees")
               .as("ass")
               .andApply(aggregationOperationContext -> {
           Document document = new Document();

           document.append("id", "$$ass.id");
           document.append("value", "$$ass.username");
           document.append("parentObjectId", "$$pr.id");

           return document;
          })
    )
).as("results");

Код производит это:

[ 
  [
    {
      "id": "201a",
      "value": "carl93",
      "parentObjectId": "101a"
    },
    {
      "id": "202a",
      "value": "susan",
      "parentObjectId": "101a"
    }
  ], 
  [
    {
      "id": "201a",
      "value": "carl93",
      "parentObjectId": "101b"
    },
    {
      "id": "202a",
      "value": "susan",
      "parentObjectId": "101b"
    }
  ]
]

Как вы можете видеть, есть 2 вложенных массива, [[], []].Это причина, по которой выбрасывается исключение.Тем не менее, я хочу получить только один массив, добавив в него все объекты (возможно, без дубликатов или нулевых значений).Я пробовал оператор addToSet и другие операторы агрегации, но безуспешно.

1 Ответ

0 голосов
/ 25 сентября 2018

Используйте $reduce с $concatArrays, чтобы присоединиться к массивам.

 new ProjectionOperation().and(
    ArrayOperators.arrayOf("processes")
      .reduce(ArrayOperators.ConcatArrays.arrayOf("$$value").concat(
           VariableOperators.mapItemsOf("$$this.ownership.assignees")
               .as("ass")
               .andApply(aggregationOperationContext -> {
           Document document = new Document();
           document.append("id", "$$ass.id");
           document.append("value", "$$ass.username");
           document.append("parentObjectId", "$$this.id");
           return document;
          })
    )).startingWith(Arrays.asList())
).as("results");
...