2011-07-29 2 views
10

Désolés si cela a déjà été demandé. Je n'ai pas trouvé de réponse définitive. Puis-je interroger un index mongodb si ma requête contient l'opérateur $ ou? Ma requête ressemble à ceci:

// find everything in the collection 
    $cursor = $collection->find(array(
    '$or' => array( 
     array('album_id' => array(
      '$in' => $this->my_album_ids 
      ), 
     'type' => array(
      '$in' => array('like','comment') 
      ) 
     ), 
     array(
    'user_id' => (int)session_item('user_id'), 
     'type' => 'message', 
     'reply' => 'no' 
     ) 
     ), 
     'timestamp' => array('$gt' => (int)$since)))->sort(array('timestamp'=>-1))->skip($start)->limit($amount); 

L'exemple est en PHP, mais je suppose que ceci est applicable à n'importe quelle langue.

Mise à jour:

Voici mes index, mais la requête ci-dessus ne les utilise pas. Cela me semble juste.

$collection->ensureIndex(array(
     'album_id' => 1, 
     'type' => 1, 
     'timestamp' => -1, 
    )); 

    $collection->ensureIndex(array(
     'user_id' => 1, 
     'type' => 1, 
     'reply' => 1, 
     'timestamp' => -1, 
    )); 

Voici mon expliquer()

Array 
(
    [cursor] => BasicCursor 
    [nscanned] => 12 
    [nscannedObjects] => 12 
    [n] => 6 
    [scanAndOrder] => 1 
    [millis] => 0 
    [nYields] => 0 
    [nChunkSkips] => 0 
    [isMultiKey] => 
    [indexOnly] => 
    [indexBounds] => Array 
     (
     ) 

    [allPlans] => Array 
     (
      [0] => Array 
       (
        [cursor] => BasicCursor 
        [indexBounds] => Array 
         (
         ) 

       ) 

     ) 

    [oldPlan] => Array 
     (
      [cursor] => BasicCursor 
      [indexBounds] => Array 
       (
       ) 

     ) 

) 

Répondre

6

Oui, un $ ou d'une requête utiliseront des index selon le cas. Par exemple:

> db.test.ensureIndex({a:1}) 
> db.test.ensureIndex({b:1}) 
> db.test.find({$or:[{a:1}, {b:2}]}).explain() 
{ 
     "clauses" : [ 
       { 
         "cursor" : "BtreeCursor a_1", 
         "nscanned" : 0, 
         "nscannedObjects" : 0, 
         "n" : 0, 
         "millis" : 0, 
         "nYields" : 0, 
         "nChunkSkips" : 0, 
         "isMultiKey" : false, 
         "indexOnly" : false, 
         "indexBounds" : { 
           "a" : [ 
             [ 
               1, 
               1 
             ] 
           ] 
         } 
       }, 
       { 
         "cursor" : "BtreeCursor b_1", 
         "nscanned" : 0, 
         "nscannedObjects" : 0, 
         "n" : 0, 
         "millis" : 1, 
         "nYields" : 0, 
         "nChunkSkips" : 0, 
         "isMultiKey" : false, 
         "indexOnly" : false, 
         "indexBounds" : { 
           "b" : [ 
             [ 
               2, 
               2 
             ] 
           ] 
         } 
       } 
     ], 
     "nscanned" : 0, 
     "nscannedObjects" : 0, 
     "n" : 0, 
     "millis" : 1 
} 
+1

Cool, il est bon de savoir qu'il est possible. Cependant, ma requête et mon index semblent toujours s'ignorer. J'ai mis à jour mon message sur la création de l'index. Est-ce que je fais quelque chose de mal? Merci. – noel

+0

Il est probable que l'une de vos clauses internes ou internes ne soit pas qualifiée pour les index spécifiés. Avez-vous expliqué() sur les parties séparées et voir si cela utilise l'index correct? Il est utile de poster des questions dans la syntaxe du shell plutôt que dans un langage spécifique. Je ne peux pas lire la plupart de ce qui précède sans plus d'effort que je suis prêt à mettre;) –

+0

Si j'étais vous, je travaillerais à travers chaque partie de votre requête en le construisant lentement, sans la clause OR. Prouvez à vous-même que l'ordre dans vos index composés est correct. Puis continuez jusqu'à la dernière requête dont vous avez besoin. Je suis sûr que votre problème sera rapidement résolu. –

4

Mongo n'utilise aucun IndexBounds sur une requête OU triée. Essayez

db.test.find({$or:[{a:1}, {b:2}]}).sort(somesort).explain(); 

et IndexBounds utiliser avec $minElement et $maxElement