Прямая копия объекта документа mongodb

Короче говоря, я работаю внутри гигантской неприятной рекурсивной функции, которая создает объект mongo Document. Мне нужно расширить функциональные возможности этой функции для поддержки сложных запросов, и мне нужно знать, как создать прямую копию (а не ссылку на объект) объекта документа mongo. Есть ли способ сделать это? Текущая реализация делает следующее:

private Document generateArrayAddsDoc(DataChanges dataChanges, Document filter)
    {
        Document arrayUpdatesDoc = new Document();
        generateArrayDocImpl(arrayUpdatesDoc, null, dataChanges, DataChanges.Type.MODEL_ADD, filter, 0);
        return arrayUpdatesDoc;
    }

Вот неприятная рекурсивная функция только для контекста:

private void generateArrayDocImpl(Document arrayUpdateDoc, String parentFieldName, DataChanges dataChanges, DataChanges.Type type, Document filter, int currentLevel)
    {
        switch (dataChanges.getType())
        {
            case MODEL_UPDATE:
            {
                for (DataChange dataChange : dataChanges.getDataChanges())
                {
                    if (dataChange.getNewValue() instanceof DataChanges)
                    {
                        DataChanges arrayChanges = (DataChanges) dataChange.getNewValue();

                        Document arrayDoc = new Document();
                        String dotFieldName = generateDotFieldName(parentFieldName, dataChange.getFieldName());

                        if (type == DataChanges.Type.MODEL_ADD || type == DataChanges.Type.MODEL_DELETE)
                        {
                            generateArrayDocImpl(arrayDoc, dotFieldName, arrayChanges, type, filter, currentLevel+1);
                        }

                        if (!arrayDoc.isEmpty())
                        {
                            if (currentLevel > 0)
                            {
                                arrayUpdateDoc.append(dotFieldName, arrayDoc);
                            }
                            else
                            {
                                arrayUpdateDoc = arrayDoc; // need to direct copy instead of referencing here
                            }
                        }
                    }
                }

                break;
            }
            case ARRAY_UPDATE:
            {
                List<Document> updateDocsList = new ArrayList<>();
                for (DataChange dataChange : dataChanges.getDataChanges())
                {
                    Document arrayElementDoc = null;
                    DataChanges arrayElementChanges = (DataChanges) dataChange.getNewValue();

                    if (arrayElementChanges.getType() == type)
                    {
                        arrayElementDoc = generateFieldUpdatesDoc(arrayElementChanges, filter);
                    }
                    else if (arrayElementChanges.getType() == DataChanges.Type.MODEL_UPDATE)
                    {
                        String dotFieldName = generateDollarSignIndexedFieldName(parentFieldName, dataChange.getFieldName());
                        generateArrayDocImpl(arrayUpdateDoc, dotFieldName, arrayElementChanges, type, filter, currentLevel+1);
                    }

                    if (null != arrayElementDoc && !arrayElementDoc.isEmpty())
                    {
                        updateDocsList.add(arrayElementDoc);
                    }
                }

                if (!updateDocsList.isEmpty() && type == DataChanges.Type.MODEL_ADD)
                {
                    arrayUpdateDoc.append("$each", updateDocsList);
                }

                if (!updateDocsList.isEmpty() && type == DataChanges.Type.MODEL_DELETE)
                {
                    String fieldName = pullFieldNameFromList(updateDocsList);
                    List<String> valuesToDelete = getValuesToDelete(updateDocsList);

                    Document doc = new Document();
                    doc.append("$in", valuesToDelete);

                    arrayUpdateDoc.append(fieldName, doc);
                }

                break;
            }
        }
    }

Если эта функция выполняет «arrayUpdateDoc = arrayDoc;», мне нужно скопировать документ в новый объект, потому что arrayDoc уничтожается после завершения вызова этой функции, что приводит к ошибке. Будем очень признательны за любые рекомендации по выполнению прямой копии объекта (не по ссылке) объекта mongo Document!

Использование JavaScript и MongoDB
Использование JavaScript и MongoDB
Сегодня я собираюсь вкратце рассказать о прототипах в JavaScript, а также представить и объяснить вам работу с базой данных MongoDB.
0
0
140
1

Ответы 1

Вы можете получить карту ввода документов и передать ее конструктору при создании нового документа:

Document original = someDocument;
Document clone = new Document(original.entrySet());

В твоем случае:

arrayUpdateDoc = new Document(arrayDoc.entrySet());

//Редактировать:

Я ошибся. Однако Document реализует Map<String, Object>. Это означает, что следующее должно работать:

arrayUpdateDoc = new Document(arrayDoc);

// Другое редактирование:

То, что вы пытаетесь сделать, не будет работать на Java. например:

public static void main(String[] args)
{
    String test = "test";
    System.out.println(test);
    someMethod(test);
    System.out.println(test);
}

public static void someMethod(String test)
{
    test = "changed";
}

вывод:

test
test

Ссылка на вызывающий абонент не будет обновлена ​​для нового объекта. Ссылка копируется при вызове метода. Итак, насколько я знаю, вам понадобится возвращаемый тип для вашего метода.

это не работает, поскольку конструктор Document (Set <String>, Set <Map.Entry <String, Object >>) не определен

Scott 14.12.2018 21:54

Это все еще не работает. Я могу заставить эту функцию работать должным образом, заставив ее возвращать новый объект в соответствии с вашим предложением, но, похоже, она все еще использует ссылку на старый объект, когда я заменяю документ, передаваемый в качестве аргумента, на вновь созданный.

Scott 14.12.2018 22:12

Я хотел бы, чтобы реализация согласовывалась с тем, что уже существует, сохраняя ее как функцию void и просто обновляя объект Document, который передается в

Scott 14.12.2018 22:12

Другие вопросы по теме