Voici quelques actions que vous pouvez effectuer :
Tout d'abord, utilisez un $in au lieu d'un $or.
Deuxièmement, MongoDB peut uniquement utilisez un indice pour votre premier match, vous devrez donc décider (en l'essayant) lequel des deux matchs est le meilleur. L'objectif est d'avoir une requête aussi rapide et le moins de documents passant par votre pipeline. Pour cela, procédez comme suit :
Commencez par créer les trois index :
db.element.ensureIndex( { 'versions.branch' : 1 } );
db.element.ensureIndex( { 'doctype' : 1 } );
db.element.ensureIndex( { 'prefix' : 1 } );
Exécutez ensuite les trois requêtes suivantes et remarquez les champs "cursor", "n", "nScanned" et "ms" :
branch = "nameofbranch"; // guessing here
db.element.find( "versions.branch": branch ).explain();
db.element.find( "doctype" { $in: [ "15281", "15282" .... ] } ).explain();
db.element.find( "prefix": { $ne: "500" } ).explain();
Pour la dernière requête, vous remarquerez que "cursor" est "BasicCursor", car une requête $ne ne peut pas utiliser l'index.
Les deux autres vous montreront différentes valeurs pour "ms", "n" et "nScanned". "ms" est le temps qu'il a fallu pour exécuter la requête. Si c'est approximativement la même chose, regardez la différence entre les valeurs "n" et "nScanned". Je vais m'attendre et deviner que la différence pour la requête "versions.branch" est de 0. Pour la requête "doctype", cela pourrait être différent. Si le "ms" n'est pas approximativement le même, mettez le $ match qui était le plus rapide d'abord en tant que clause $match dans votre pipeline d'agrégation.
Si la vitesse ("ms") est la même, vérifiez les valeurs "n". Si le "n" pour la requête "préfixe" est disons "5" et le "n" pour la requête "versions.branch" est "500", cela signifie que le résultat de la requête "préfixe" est meilleur, car moins les documents sont retournés. Dans ce cas, mettez cela comme votre première clause $match dans l'ensemble. Si "versions.branch" est bien inférieur, utilisez celui-ci comme première clause $match.