2013-07-15 11 views
2

Je souhaite créer un index sur un champ qui contiendra des tableaux. Par défaut, mongo indexe chaque élément séparément dans chaque tableau lorsqu'un index est créé dans un tel champ.Création d'un index composé sur un champ de tableau unique

Toutefois, je souhaite que l'index soit à la place un index composé, similaire à un index sur un champ de sous-document (je veux que l'index soit unique et ['a', 'b'] être distinct de ['b', 'a']). Y at-il un moyen de le faire en monogo?

+0

Est-ce que ce doit être un tableau? –

+0

Eh bien, il doit s'agir d'une sorte de champ multi-valeur de longueur arbitraire. Un tableau est la seule chose qui correspond à la facture que je connais ... – thecoop

+0

Vous pouvez le stocker dans une chaîne, '" a, b "' et gérer des éléments individuels dans l'application. –

Répondre

0

Vous pouvez le faire en stockant les données comme suit:

{ 
    field: { v: [ a, "b" ] } 
} 

Et puis faire un index sur:

db.collection.ensureIndex({ field: 1 }); 

Je sais qu'il est un peu contre-intuitif, mais un index sur « terrain "utilisera maintenant comme valeur d'index:

v: [ a, "b" ] 

Et pas chaque a et" b "individuellement. Bien sûr, vous pouvez utiliser quelque chose d'autre pour "v", mais il est important que la valeur de champ soit un document, et non un tableau.

Une requête sur:

db.collection.find({ field: { v: [ 'a', 'b' ] } }) 

utilisera alors heureusement l'index:

{ 
    "cursor" : "BtreeCursor field_1", 
    "isMultiKey" : false, 
    "n" : 1, 
    "nscannedObjects" : 1, 
    "nscanned" : 1, 
    "nscannedObjectsAllPlans" : 1, 
    "nscannedAllPlans" : 1, 
    "scanAndOrder" : false, 
    "indexOnly" : false, 
    "nYields" : 0, 
    "nChunkSkips" : 0, 
    "millis" : 0, 
    "indexBounds" : { 
     "field" : [ 
      [ 
       { 
        "v" : [ "a", "b" ] 
       }, 
       { 
        "v" : [ "a", "b" ] 
       } 
      ] 
     ] 
    }, 
    "server" : "whisky:27017" 
} 
+0

Est-ce que cela utilise réellement un index si vous utilisez la valeur composée dans une requête? Je pense que ça ne va pas. – WiredPrairie

+0

Bien sûr, j'ai clarifié ma réponse. – Derick

-1

Pour la question de savoir si elle utilise l'index lorsque vous index sur un champ d'emballage, oui, il utilise Un index. Les déclarations suivantes du shell le prouvent.

> db.arrayindtest.insert({_id:1, f:{a:["a","b"]}}) 
> db.arrayindtest.insert({_id:2, f:{a:["b","a"]}}) 
> db.arrayindtest.insert({_id:3, f:{a:["a","b", "c"]}}) 
> db.arrayindtest.ensureIndex({f:1}) 
> db.arrayindtest.find({f:{a:["a","b"]}}) 
{ "_id" : 1, "f" : { "a" : [ "a", "b" ] } } 
> db.arrayindtest.find({f:{a:["a","b"]}}).explain() 
{ 
     "cursor" : "BtreeCursor f_1", 
     "isMultiKey" : false, 
     "n" : 1, 
     "nscannedObjects" : 1, 
     "nscanned" : 1, 
     "nscannedObjectsAllPlans" : 1, 
     "nscannedAllPlans" : 1, 
     "scanAndOrder" : false, 
     "indexOnly" : false, 
     "nYields" : 0, 
     "nChunkSkips" : 0, 
     "millis" : 0, 
     "indexBounds" : { 
       "f" : [ 
         [ 
           { 
             "a" : [ 
               "a", 
               "b" 
             ] 
           }, 
           { 
             "a" : [ 
               "a", 
               "b" 
             ] 
           } 
         ] 
       ] 
     }, 
     "server" : "sridhar-PC:27017" 
} 
> 
Questions connexes