2011-11-18 10 views
7

Ben benziyor benim users koleksiyonunda veri varsa:

{ name: '...', 
    email: '...', 
    ..., 
    photos: { 
    123: { url: '...', title: '...', ... }, 
    456: { url: '...', title: '...', ... }, 
    ... 
    } 
} 

Ve hangi kullanıcı bulmak istiyorum fotoğraflı kimlik 127 sahibi, ben sorguyu kullanıyorum o zaman: Ben ettik

db.users.find({'photos.127': {'$exists' => true} }); 

denedi, ancak MongoDB'nin bu sorgu için bir dizin kullanması mümkün görünmüyor. Denediğim indeks: db.users.ensureIndex({photos:1});. Ve ben explain() mongo kullandığında, bir BasicCursor kullandığını söyledi (yani, indeks kullanıldı).

bu sorgu için kullanacağı Mongo bir dizin oluşturmak mümkün mü?

cevap

12

Hayır, sorgu var için endeksini kullanmayı MongoDB söylemenin hiçbir yolu yoktur. Dizin Oluşturma, veriler ile ilgilidir. $ mevcut olduğundan sadece anahtar (alan) ile ilgili olduğu için dizinlerde kullanılamaz.

$ sadece verilen anahtar (veya alan) belgesinde var olup olmadığını doğrular vardır.

+0

vardır. – bantic

+8

NO !!! Ben mongodb 2.4.3 ile test ettim ve endeksi kullanır. Varolmayan alanların, dizinde Null değerine sahip olduğunu unutmayın. –

+2

MongoDB 3.0.3: 'açıkla' bul ({field: {$ exists: 1}}) 've' find ({field: {$ ne: null}}) 'indeksi kullanacak gibi görünüyor ama ikinci sorgu anında biterse, ilk bir tanesi (w/full scan, sanırım). – vorou

6

$ endeksi kullanmaz var, ancak

photos: [ 
    {id:123, url: '...', title: '...', ... }, 
    {id:456, url: '...', title: '...', ... }, 
    ... 
    ] 

için veri yapısını değiştirmek ve daha sonra fotoğraf kimliği için dizin oluşturmak için

db.users.ensureIndex({photos.id:1}) 

kullanabilirsiniz.

yanlış mıyım görünüyor, aslında, sizin $ zorlayabilir endeksinizi kullanmak için sorguyu bulunmaktadır. Yukarıdaki yapıyı kullanmaya devam edelim, ancak fotoğraf kimliğiniz kesinlikle belirtilmiyor, yani bazı dokümanlarda 'id' anahtarına sahip olacak ve bazıları olmayacak. Sonra üzerine seyrek endeksi oluşturabilirsiniz:

db.users.ensureIndex({'photos.id': 1}, {'sparse': true}) 

sonra böyle sorgulamak:

db.users.find({'photos.id': {$exists: true}}).hint({'photos.id': 1}) 

sorgu dizini kullanarak olup olmadığını görmek için açıklamak ekleyebilir. İşte benim sonucudur, benim koleksiyonun mobil anahtarı photos.id benzer: yardımcı

> db.test.count() 
50000 
> db.test.find({'mobile': {$exists: true}}).hint({'mobile': 1}).explain() 
{ 
     "cursor" : "BtreeCursor mobile_1", 
     "nscanned" : 49999, 
     "nscannedObjects" : 49999, 
     "n" : 49999, 
     "millis" : 138, 
     "nYields" : 0, 
     "nChunkSkips" : 0, 
     "isMultiKey" : false, 
     "indexOnly" : false, 
     "indexBounds" : { 
       "mobile" : [ 
         [ 
           { 
             "$minElement" : 1 
           }, 
           { 
             "$maxElement" : 1 
           } 
         ] 
       ] 
     } 
} 

> db.test.getIndexes() 
[ 
     { 
       "v" : 1, 
       "key" : { 
         "_id" : 1 
       }, 
       "ns" : "test.test", 
       "name" : "_id_" 
     }, 
     { 
       "v" : 1, 
       "key" : { 
         "mobile" : 1 
       }, 
       "ns" : "test.test", 
       "name" : "mobile_1", 
       "sparse" : true, 
       "background" : true 
     } 
] 

Umut!

İlgili konular