Відповідно до документації mongoldb , комбінаціяdistinct
Знаходить виразні значення для вказаного поля в одній колекції або перегляді та повертає результати в масив.
і операції збору індексів - це те, що поверне всі можливі значення для даного ключа або індексу:
Повертає масив, який містить список документів, що ідентифікують та описують наявні індекси колекції
Тож у даному методі можна було б скористатись таким методом, як наступний, для запиту колекції для всіх зареєстрованих індексів та повернення, скажімо, об’єкт із індексами для ключів (у цьому прикладі використовується async / wait для NodeJS, але очевидно, ви можете використовувати будь-який інший асинхронний підхід):
async function GetFor(collection, index) {
let currentIndexes;
let indexNames = [];
let final = {};
let vals = [];
try {
currentIndexes = await collection.indexes();
await ParseIndexes();
//Check if a specific index was queried, otherwise, iterate for all existing indexes
if (index && typeof index === "string") return await ParseFor(index, indexNames);
await ParseDoc(indexNames);
await Promise.all(vals);
return final;
} catch (e) {
throw e;
}
function ParseIndexes() {
return new Promise(function (result) {
let err;
for (let ind in currentIndexes) {
let index = currentIndexes[ind];
if (!index) {
err = "No Key For Index "+index; break;
}
let Name = Object.keys(index.key);
if (Name.length === 0) {
err = "No Name For Index"; break;
}
indexNames.push(Name[0]);
}
return result(err ? Promise.reject(err) : Promise.resolve());
})
}
async function ParseFor(index, inDoc) {
if (inDoc.indexOf(index) === -1) throw "No Such Index In Collection";
try {
await DistinctFor(index);
return final;
} catch (e) {
throw e
}
}
function ParseDoc(doc) {
return new Promise(function (result) {
let err;
for (let index in doc) {
let key = doc[index];
if (!key) {
err = "No Key For Index "+index; break;
}
vals.push(new Promise(function (pushed) {
DistinctFor(key)
.then(pushed)
.catch(function (err) {
return pushed(Promise.resolve());
})
}))
}
return result(err ? Promise.reject(err) : Promise.resolve());
})
}
async function DistinctFor(key) {
if (!key) throw "Key Is Undefined";
try {
final[key] = await collection.distinct(key);
} catch (e) {
final[key] = 'failed';
throw e;
}
}
}
Отже, запитуючи колекцію з базовим _id
індексом, повернеться наступне (тестова колекція має лише один документ на момент проведення тесту):
Mongo.MongoClient.connect(url, function (err, client) {
assert.equal(null, err);
let collection = client.db('my db').collection('the targeted collection');
GetFor(collection, '_id')
.then(function () {
//returns
// { _id: [ 5ae901e77e322342de1fb701 ] }
})
.catch(function (err) {
//manage your error..
})
});
Зауважте, для цього використовуються методи, які є власними для драйвера NodeJS. Як підказують деякі інші відповіді, існують і інші підходи, наприклад, сукупний фреймворк. Я особисто вважаю цей підхід більш гнучким, оскільки ви можете легко створити і налагодити, як повернути результати. Очевидно, що це стосується лише атрибутів верхнього рівня, а не вкладених. Крім того, щоб гарантувати представлення всіх документів у разі наявності вторинних індексів (крім головного _id), ці індекси повинні бути встановлені як required
.