Несколько массивов MongoDB с уникальными значениями

Я столкнулся с небольшой дилеммой при создании схемы и настройке моей базы данных "правильным" способом. У меня есть коллекция, содержащая объекты, содержащие 4 разных массива. Объекты в записях коллекции выглядят примерно так:

itemInCollection{
    ...
    theObj: {arr1: ["user1685", "user5342"], arr2: ["user1432"], arr3: [], arr4: ["user1632", "user2312", "user6452"]},
    ...
}

Схема, которую я сделал, уже требует, чтобы все элементы массива были уникальными, но я также хочу, чтобы ни один из массивов не содержал ту же запись, что и другой. Мне также нужно иногда перемещать элемент, который уже находится в одном массиве, в другой массив (и, конечно, удалять запись из старого массива, потому что ни один из массивов не должен содержать одну и ту же запись). Очевидно, это не лучший способ отслеживать что-то подобное, или нет?

На данный момент у меня есть 4 запроса, которые проверяют каждый массив отдельно для определенной записи, и еще один запрос, который добавляет запись в соответствующий массив, если запись не найдена... и ДРУГОЙ запрос, который удалит запись, которая могла быть найдена в другом, прежде чем добавлять его в другой массив.

Есть ли лучший способ настроить базу данных для отслеживания чего-то подобного? Или есть динамический способ запроса нескольких массивов вместо использования 6-7 разных запросов?

Заранее всем спасибо за ваше время и помощь :)


person hewiefreeman    schedule 15.08.2018    source источник


Ответы (1)


Вы можете структурировать свои «пользовательские» данные как вложенные документы, а не как строки, подобные этому:

itemInCollection{
    ...
    theObj: [
        { userid: "user1685", type: "arr1" },
        { userid: "user5342", type: "arr1" },
        { userid: "user1432", type: "arr2" },
        { userid: "user1632", type: "arr4" },
        { userid: "user2312", type: "arr4" },
        { userid: "user6452", type: "arr4" }
    ],
    ...
}

С такой структурой обеспечить уникальность должно быть проще (на данном этапе, к сожалению, нет способа обеспечить уникальность конкретного поля внутри массива — см. эта ссылка).

person dnickless    schedule 15.08.2018
comment
Теоретически, если бы я использовал это и знал идентификатор нужного элемента коллекции, должен ли я использовать что-то вроде db.collection.find({"_id": theID, "theObj": {$elemMatch: {"userID": "someUser"}}}), чтобы проверить, находится ли пользователь в массиве, и либо заменить элемент, либо вставить новый? Или есть операция upsert, которая бы выполняла оба действия одновременно? - person hewiefreeman; 16.08.2018
comment
Это действительно смешно. И, да, есть операция upsert, которая, однако, не очень поможет из-за массива... См. эту ссылку: stackoverflow.com/questions/13588342/ - person dnickless; 16.08.2018
comment
Я рассмотрю это немного подробнее... но вы также говорите, что создание схемы, указывающей, что theObj имеет уникальные элементы, не будет работать в этом случае, потому что они являются документами? - person hewiefreeman; 16.08.2018
comment
Да, боюсь, что да. Вы можете сделать некоторые биты уникальными, но только для документов, а не внутри массива конкретного документа. Этого просто нельзя делать. Но вы можете контролировать эту уникальность при обновлении ваших массивов, используя $addToSet вместо $push. - person dnickless; 17.08.2018