Невозможно извлечь из вложенного массива и вернуть вложенный документ запроса с помощью MongoTemplate - PullRequest
0 голосов
/ 03 марта 2020

Я использую Mongodb в Springboot. И вот часть моих данных:

{
  "topic": [
    {
      "_topicId": "5e5e4d4bb431502946c15342",
      "name": "testName0",
      "username": "test0",
      "date": 1583238474961,
      "reply": [
        {
          "_replyId": "38d29dcb-1a79-4788-b721-5fbe700cc99d",
          "username": "test0",
          "content": "reply0",
          "date": 1583240780072
        },
        {
          "_replyId": "07a0293a-22a1-45fb-9aa2-775fa24e9915",
          "username": "test1",
          "content": "reply1",
          "date": 1583240955561
        }
      ]
    },
    {
      "_topicId": "5e5e4d4bb431502946c15343",
      "name": "testName1",
      "username": "test1",
      "date": 1583238475241,
      "reply": []
    }
  ]
}

У меня есть две проблемы:

(1) Я пытаюсь вытащить reply (объект в java) из topic, я пытаюсь выполнить следующие запросы:

Query query = Query.query(Criteria.where("_topicId").is(topicId));
Update update = new Update().pull("reply.$._replyId", topicReplyId);
mongoTemplate.updateFirst(query, update, "colletionName");

И я получил ошибку Позиционный оператор не нашел нужного соответствия из запроса

Query query = Query.query(Criteria.where("_topicId").is(topicId));
Update update = new Update().pull("reply._replyId", topicReplyId);
mongoTemplate.updateFirst(query, update, "colletionName");

И я получил ошибку Невозможно использовать часть (_replyId) (reply._replyId) для прохождения элемента

Затем я решаю использовать третий способ:

Query query = Query.query(Criteria.where("_topicId").is(topicId));
Update update = new Update().pull("reply", replyEntity);
mongoTemplate.updateFirst(query, update, "colletionName");

Я пытаюсь создать ReplyEntity replyEntity, и у меня есть вторая проблема :

(2) Как я могу получить поддокумент из документа?

Query query = Query.query(Criteria.where("_topicId").is(topicId).and("reply._replyId").is(replyId));
TopicEntity t = mongoTemplate.findOne(query, TopicEntity.class, "colletionName");

Я использовал запрос, но получаю внешний документ (topic), включив два reply на примере выше темы1. Я просто хочу reply, как это можно сделать? Большое спасибо.

1 Ответ

1 голос
/ 04 марта 2020

(1) Обновить (вытащить) reply элемент массива:

Этот код обновит документ; то есть удаляет указанный элемент c (поддокумент) из массива reply:

// Query criteria for topic and reply
String topicId = "5e5e4d4bb431502946c15342";
String topicReplyId = "07a0293a-22a1-45fb-9aa2-775fa24e9915";

MongoOperations mongoTemplate = new MongoTemplate(MongoClients.create(), "test");
Query query = Query.query(Criteria
                               .where("topic._topicId").is(topicId)
                               .and("topic.reply._replyId").is(topicReplyId));
Update update = new Update().pull("topic.$.reply", new Document("_replyId", topicReplyId));
mongoTemplate.updateFirst(query, update, "topics"); // "topics" is the collection name



[EDIT ADD]

(2) Запрос агрегации для получения документа reply:

db.topics.aggregate( [
  { $unwind: "$topic" },
  { $match: { "topic._topicId": topicId } },
  { $unwind: "$topic.reply" },
  { $match: { "topic.reply._replyId": topicReplyId } },
  { $project: { _id: 0, reply: "$topic.reply" } }
] ).pretty()

Возвращает:

{
        "reply" : {
                "_replyId" : "07a0293a-22a1-45fb-9aa2-775fa24e9915",
                "username" : "test1",
                "content" : "reply1",
                "date" : 1583240955561
        }
}
...