2010-12-09 16 views
21

Büyük bir koleksiyon (300k + kayıtları) depolamak için MongoDB 1.6.3 kullanıyorum. Bir bileşik endeks ekledim. AncakMongoDB - index hatası olmadan sort() için çok fazla veri

db['collection_name'].getIndexes() 
[ 
    { 
     "name" : "_id_", 
     "ns" : "db_name.event_logs", 
     "key" : { 
      "_id" : 1 
     } 
    }, 
    { 
     "key" : { 
      "updated_at.t" : -1, 
      "community_id" : 1 
     }, 
     "ns" : "db_name.event_logs", 
     "background" : true, 
     "name" : "updated_at.t_-1_community_id_1" 
    } 
] 

, ben bu kodu çalıştırmayı deneyin: alıyorum

db['collection_name'] 
    .find({:community_id => 1}) 
    .sort(['updated_at.t', -1]) 
    .skip(@skip) 
    .limit(@limit) 

:

Mongo :: OperationFailure (çok fazla veri sıralama için () hiçbir indeksi Bir dizinini ekleyin veya daha küçük bir sınır belirtin)

Neyi yanlış yapıyorum?

cevap

14

{community_id: 1, 'updated_at.t': -1} dizini eklemeye çalışın. Önce community_id ile arama yapmalı ve ardından sıralamalıdır.

+2

Sıralama sütunu, dizinin son sütunu olmalıdır. http://www.mongodb.org/display/DOCS/Indexing+Advice+and+FAQ#IndexingAdviceandFAQ-1.Thesortcolumnmustbethelastcolumnusedintheindex. –

4

Dizin kullandığınız gibi "hissediyor", ancak dizin aslında bir bileşik dizin. Bu türün yalnızca kısmi dizini kullanmak için "yeterince akıllı" olduğundan emin değilim.

Yani iki sorun: Sorgunuzda üzerine

  1. dayanarak, endeks değil, ikinci ilk bölümü olarak topluluk_kimliği koyardı. updated_at.t, aralık sorguları yapacağınız bir alan gibi görünüyor. Aralık sorguları ikinci bit ise dizinler daha iyi çalışır.
  2. community_id => 1 dan kaç tane giriş var? Eğer sayı büyük değilse, endeks olmadan sadece sıralama yapmaktan kurtulabilirsiniz.

Yani etrafında endeksi geçmek olabilir ve community_id ve updated_at.t ikisini de kullanmak tür değiştirmek gerekebilir. Biliyorum gereksiz görünüyor, ancak oradan başla ve hala çalışmıyorsa Google Gruplarını kontrol et.

2

Bir endeksle bile, sonuç kümeniz 4 MB'yi aşarsa yine de bu hatayı alabileceğinizi düşünüyorum.

Sen mongodb konsola gidip bunu yaparak boyutunu görebilirsiniz

:

show dbs 
# pick yours (e.g., production) 
use db-production 
db.articles.stats 

böyle sonuçlarla sona erdi:

{ 
"ns" : "mdalert-production.encounters", 
"count" : 89077, 
"size" : 62974416, 
"avgObjSize" : 706.9660630690302, 
"storageSize" : 85170176, 
"numExtents" : 8, 
"nindexes" : 6, 
"lastExtentSize" : 25819648, 
"paddingFactor" : 1, 
"flags" : 1, 
"totalIndexSize" : 18808832, 
"indexSizes" : { 
    "_id_" : 3719168, 
    "patient_num_1" : 3440640, 
    "msg_timestamp_1" : 2981888, 
    "practice_id_1" : 2342912, 
    "patient_id_1" : 3342336, 
    "msg_timestamp_-1" : 2981888 
}, 
"ok" : 1 
} 
0

çok büyük bir imleç toplu boyutu olması bu hataya neden olur. Parti boyutunu ayarlamak, işleyebileceğiniz veri miktarını sınırlandırmaz, sadece veritabanından ne kadar veri getirildiğini sınırlar. Yineleyin ve toplu sınırı vurduğunuzda, işlem veritabanına başka bir gezi yapar.