Mongodb _id имеет два разных типа данных в одной коллекции

#node.js #mongodb #graphql #express-graphql

#node.js #mongodb #graphql #express-graphql

Вопрос:

Проект, над которым я работаю, использует mongodb в качестве базы данных и имеет макет генератора данных. когда данные генерируются с помощью генератора макетных данных, он создает объекты со строковыми идентификаторами в БД. И наше серверное приложение Spring boot с весенними данными mongodb сохраняет новые объекты с _id, являющимся ObjectId

 {
    "_id" : ObjectId("6163686f6c64722d30303031"),
    "email" : "Price36@hotmail.com",
    "modeOfContact" : "EMAIL",
    "name" : "Leonardo Walter",
    "phone" : "08802273531"
}

{
    "_id" : "customer-1",
    "email" : "Casimer_Jakubowski@hotmail.com",
    "modeOfContact" : "EMAIL",
    "name" : "Kennedy Kilback",
    "phone" : "07624333004"
}
  

теперь у нас есть приложение на основе узла только для вызовов выборки, которое использует пакет «mongodb» для разрешения запросов.

когда я выполняю следующий запрос для объектов со строкой _id, это работает

 findDocument(COLLECTION_NAME, { _id: args.id})
  

но запрос завершается ошибкой, когда объекты имеют _id в качестве ObjectId

есть ли способ, с помощью которого я могу выполнять поиск объектов, также предоставляя _id и тип данных
, например

 findDocument(COLLECTION_NAME, {  _id: args.id , $type: [ 'string', 'ObjectId']})
  

я знаю, что с помощью $type он вернет все записи с _id, соответствующими этому типу. просто пытаюсь объяснить, чего я хочу здесь добиться.

Ответ №1:

но запрос завершается ошибкой, когда объекты имеют _id в качестве ObjectId

Для запроса ObjectId в mongo из nodejs вам необходимо создать ObjectId:

 var ObjectID = require('mongodb').ObjectID;

// Create a new ObjectID (hex string is 24 characters long)
var objectId = new ObjectID('6163686f6c64722d30303031');

// NOTE: you try to run `new ObjectID('customer-1');` you will get an Exception

findDocument(COLLECTION_NAME, { _id: objectId})
  

Я думаю, лучшим подходом было бы обновить ваш макет, чтобы вставить valid ObjectID вместо строки, если для вас это не имеет значения, потому что вам нужно гарантировать уникальность _id

Комментарии:

1. спасибо @Manuel за ответ, но иногда я получаю _id в виде строки, а иногда ObjectId из интерфейса. Я попробовал ваше решение, и оно будет работать, когда _id, поступающий из интерфейса, является шестнадцатеричной строкой, иначе это вызовет исключение.

2. Также я пытался добавить ObjectId через фиктивные данные, в некоторых коллекциях у меня есть ссылки на объекты внутри некоторых объектов. В этом случае на моей стороне Java я получаю результаты только при запросе с полем _id, т. Е. _id является ObjectId, и когда я запрашиваю со ссылкой внутри моего объекта, я получаю нулевой результат. ` SomeEntity findById(String id)` возвращает ожидаемый результат, поскольку _id — это ObjectId, но SomeEntity findByReferenceId(String refId) возвращает нулевые результаты, поскольку ReferenceId — это просто шестнадцатеричная строка

3. Если у вас смешанный формат, вы могли бы просто добавить try{}catch{} при создании нового ObjectId

4. Да, конечно, на данный момент это кажется быстрым решением

Ответ №2:

запрос завершается ошибкой, когда объекты имеют _id в качестве ObjectId

Один из способов добиться этого — использовать ObjectID конструкцию только тогда, когда ее допустимое ObjectId использование ObjectID.isValid()

 const mongodb = require("mongodb").ObjectID;

const validId = mongodb.ObjectID.isValid(args._id);
/*only convert to ObjectID if validId true*/
const idToQuery = validId ? new mongodb.ObjectID(args._id) : args._id;

findDocument(COLLECTION_NAME, { _id: idToQuery });