Порівнюючи мангусту _id та рядки


197

У мене є додаток node.js, який витягує деякі дані і вставляє їх в об'єкт, як це:

var results = new Object();

User.findOne(query, function(err, u) {
    results.userId = u._id;
}

Коли я роблю if / then на основі цього збереженого ідентифікатора, порівняння ніколи не відповідає дійсності:

if (results.userId == AnotherMongoDocument._id) {
    console.log('This is never true');
}

Коли я роблю console.log з двох ідентифікаторів, вони точно відповідають:

User id: 4fc67871349bb7bf6a000002 AnotherMongoDocument id: 4fc67871349bb7bf6a000002

Я припускаю, що це якась проблема типу даних, але я не впевнений, як конвертувати results.userId у тип даних, що призведе до того, що вищезгадане порівняння є істинним, і мій аутсорсинговий мозок (він же Google) не зміг допомогти.

Відповіді:


361

Mongoose використовує власний драйвер mongodb, який використовує користувацький тип ObjectID. Ви можете порівняти ObjectID з .equals()методом. З вашим прикладом results.userId.equals(AnotherMongoDocument._id). Тип ObjectID також має toString()метод, якщо ви хочете зберігати впорядкованій версії ObjectID у форматі JSON або файлі cookie.

Якщо ви користуєтесь ObjectID = require("mongodb").ObjectID(потрібна рідна бібліотека mongodb), ви можете перевірити, чи results.userIdдійсний ідентифікатор results.userId instanceof ObjectID.

І т.д.



4
Якщо ви вже використовуєте, mongooseви можете просто require('mongoose').mongo.ObjectIDтак, що вам не доведеться перераховувати додаткові залежності
JoshuaDavid

63

ObjectIDs - це об'єкти, тому якщо ви просто порівнюєте їх з ==ти порівнюєш їх посилання. Якщо ви хочете порівняти їх значення, вам потрібно скористатися ObjectID.equalsметодом:

if (results.userId.equals(AnotherMongoDocument._id)) {
    ...
}

17

перетворення ідентифікатора об'єкта в рядок (використовуючи метод toString ()) зробить цю роботу.


8

Прийняті відповіді дійсно обмежують те, що ви можете зробити зі своїм кодом. Наприклад, ви не зможете шукати масив Object Ids, використовуючи метод equals. Натомість було б більше сенсу завжди передавати рядки та порівнювати клавіші.

Ось приклад відповіді у випадку, якщо вам потрібно скористатися indexOf()для перевірки в масиві посилань на певний ідентифікатор. припустимо query, це запит, який ви виконуєте, припустімо someModel, що це модель монго для ідентифікатора, який ви шукаєте, і, нарешті, припустити, results.idListце поле, в якому ви шукаєте ідентифікатор вашого об'єкта.

query.exec(function(err,results){
   var array = results.idList.map(function(v){ return v.toString(); });
   var exists = array.indexOf(someModel._id.toString()) >= 0;
   console.log(exists);
});

1
або однолінійний:let exists = results.idList.filter(val => val.toString() === thisIsTheStringifiedIdWeAreLookingFor).length ? true : false
Златко

4
@ Zlatko Я не великий прихильник нового синтаксису, але кожного свого.
r3wt

2
@Zlatko const exists = results.idList.some(val => val.toString() === thisIsTheStringifiedIdWeAreLookingFor) або const exists = results.idList.some(val => val.equals(someModel._id))
axanpi

1
@ Zlatko всі ці роки пізніше, і вгадай, що. Я вважаю за краще, щоб ваша версія була моєю зараз. розум, якщо я додам його до своєї відповіді з належним віднесенням?
r3wt

1
Ціна прогресу :) Звичайно, ви можете скористатися відповіддю, його метою було надати альтернативу чи допомогу, якщо це можливо.
Златко

6

Відповідно до сказаного, я знайшов три способи вирішити проблему.

  1. AnotherMongoDocument._id.toString()
  2. JSON.stringify(AnotherMongoDocument._id)
  3. results.userId.equals(AnotherMongoDocument._id)

0

Я зіткнувся з точно такою ж проблемою, і я просто вирішив проблему за допомогою JSON.stringify()наступного: -

if (JSON.stringify(results.userId) === JSON.stringify(AnotherMongoDocument._id)) {
        console.log('This is never true');
}

0

Три можливі рішення, запропоновані тут, мають різні випадки використання.

  1. Використовуйте .equals при порівнянні ObjectID на двох подібних документах mongoDocuments

    results.userId.equals (AnotherMongoDocument._id)

  2. Використовуйте .toString () для порівняння рядкового представлення ObjectID з ObjectID mongoDocument. подобається це

    results.userId === AnotherMongoDocument._id.toString ()


Яке третє можливе рішення?
Кріс Катіньяні
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.