Selon la documentation de mongoldb , une combinaison dedistinct
Recherche les valeurs distinctes d'un champ spécifié dans une seule collection ou vue et renvoie les résultats dans un tableau.
et les opérations de collecte d' index sont ce qui retournerait toutes les valeurs possibles pour une clé ou un index donné:
Renvoie un tableau contenant une liste de documents qui identifient et décrivent les index existants sur la collection
Donc, dans une méthode donnée, on pourrait utiliser une méthode comme la suivante, afin d'interroger une collection pour tous ses index enregistrés, et retourner, par exemple, un objet avec les index pour les clés (cet exemple utilise async / wait pour NodeJS, mais vous pouvez évidemment utiliser toute autre approche asynchrone):
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;
}
}
}
Donc, interroger une collection avec l' _id
index de base , retournerait ce qui suit (la collection de test n'a qu'un seul document au moment du test):
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..
})
});
Attention, cela utilise des méthodes natives du pilote NodeJS. Comme certaines autres réponses l'ont suggéré, il existe d'autres approches, comme le cadre global. Personnellement, je trouve cette approche plus flexible, car vous pouvez facilement créer et affiner comment renvoyer les résultats. De toute évidence, cela ne concerne que les attributs de niveau supérieur, pas ceux imbriqués. De plus, pour garantir que tous les documents sont représentés s'il existe des index secondaires (autres que le _id principal), ces index doivent être définis comme required
.