Changeset 9804


Ignore:
Timestamp:
10/30/10 00:34:48 (3 years ago)
Author:
SvenDowideit
Message:

Item9893: auto add indexes until it won't let you anymore - this isn't a solution, but I want to get it into the history so that later we know why we can't do this

Location:
trunk/MongoDBPlugin/lib/Foswiki/Plugins
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/MongoDBPlugin/lib/Foswiki/Plugins/MongoDBPlugin.pm

    r9782 r9804  
    173173            my $FIELD = $savedMeta->{$key}; 
    174174            $meta->{$key} = {}; 
     175             
    175176            foreach my $elem (@$FIELD) { 
     177                if ($key eq 'FIELD') { 
     178                    #TODO: move this into the search algo, so it makes an index the first time someone builds an app that sorts on it. 
     179                    #even then, we have a hard limit of 40 indexes, so we're going to have to get more creative. 
     180                    #mind you, we don't really need indexes for speed, just to cope with query() resultsets that contain more than 1Meg of documents - so maybe we can delay creation until that happens? 
     181                    getMongoDB()->ensureIndex( 'current', { $key.'.'.$elem->{name} => 1 }, {name=>$key.'.'.$elem->{name}}); 
     182                } 
     183                 
    176184                $meta->{$key}{ $elem->{name} } = $elem; 
    177185            } 
  • trunk/MongoDBPlugin/lib/Foswiki/Plugins/MongoDBPlugin/DB.pm

    r9567 r9804  
    4949 
    5050#TODO: not the most efficient place to create and index, but I want to be sure, to be sure. 
    51     $collection->ensure_index( { _topic => 1 } ); 
    52     $collection->ensure_index( { _topic => 1, _web => 1 }, { unique => 1 } ); 
    53 #TODO: really should use the auto indexed '_id' (or maybe we can use this as a tuid - unique foreach rev of each topic..) 
     51    $self->ensureIndex( $collection, { _topic => 1 }, {name=>'_topic'}); 
     52    $self->ensureIndex( $collection, { _topic => 1, _web => 1 }, { name=>'_topic:_web', unique => 1 } ); 
     53    $self->ensureIndex( $collection, { 'TOPICINFO.author' => 1 }, {name=>'TOPICINFO.author'} ); 
     54    $self->ensureIndex( $collection, { 'TOPICINFO.date' => 1  }, {name=>'TOPICINFO.date'} ); 
     55    $self->ensureIndex( $collection, { 'TOPICPARENT.name' => 1  }, {name=>'TOPICPARENT.name'} ); 
     56 
     57#TODO: maybe should use the auto indexed '_id' (or maybe we can use this as a tuid - unique foreach rev of each topic..) 
     58#then again, atm, its totally random, so may be good for sharding. 
    5459 
    5560    $collection->update( 
     
    5964    ); 
    6065} 
     66 
     67 
     68#BUGGER. compound indexes won't help with large queries 
     69#> db.current.dropIndexes();                                      
     70#{ 
     71#       "nIndexesWas" : 2, 
     72#       "msg" : "non-_id indexes dropped for collection", 
     73#       "ok" : 1 
     74#} 
     75#> db.current.find().sort({_topic:1}) 
     76#error: { 
     77#       "$err" : "too much data for sort() with no index.  add an index or specify a smaller limit", 
     78#       "code" : 10128 
     79#} 
     80#> db.current.ensureIndex({_web:1, _topic:1, 'TOPICINFO.date':1, 'TOPICINFO.author': 1}); 
     81#> db.current.find().sort({_topic:1}) 
     82#error: { 
     83#       "$err" : "too much data for sort() with no index.  add an index or specify a smaller limit", 
     84#       "code" : 10128 
     85#} 
     86#>  
     87#    $collection->ensure_index( { 'TOPICINFO.author' => 1, 'TOPICINFO.date' => 1, 'TOPICPARENT.name' => 1  } ); 
     88#    $collection->ensure_index( { 'TOPICINFO.author' => -1, 'TOPICINFO.date' => -1, 'TOPICPARENT.name' => -1  } ); 
     89#MongoDB's ensure_index causes the server to re0index, even if that index already exists, so we need to wrap it. 
     90sub ensureIndex { 
     91    my $self = shift; 
     92    my $collection = shift; #either a collection object of a name 
     93    my $indexRef = shift;   #can be a hashref or an ixHash 
     94    my $options = shift; 
     95     
     96    ASSERT(defined($options->{name})) if DEBUG; 
     97     
     98    if (ref($collection) eq '') { 
     99        #convert name of collection to collection obj 
     100        $collection = $self->_getCollection($collection); 
     101    } 
     102     
     103    #cache the indexes we know about 
     104    if (not defined($self->{mongoDBIndexes})) { 
     105        my @indexes = $collection->get_indexes(); 
     106        $self->{mongoDBIndexes} = \@indexes; 
     107    } 
     108    foreach my $index (@{$self->{mongoDBIndexes}})  { 
     109        #print STDERR "we already have:  ".$index->{name}." index\n"; 
     110        if ($options->{name} eq $index->{name}) { 
     111            #already exists, do nothing. 
     112            return; 
     113        } 
     114    } 
     115    if (scalar(@{$self->{mongoDBIndexes}}) >= 40) { 
     116        print STDERR "*******************ouch. MongoDB can only have 40 indexes per collection\n"; 
     117        return; 
     118    } 
     119print STDERR "creating ".$options->{name}." index\n"; 
     120    #TODO: consider doing these in a batch at the end of a request, or? 
     121    $collection->ensure_index($indexRef, $options); 
     122    undef $self->{mongoDBIndexes}; #clear the cache :/ 
     123} 
     124 
    61125 
    62126sub remove { 
Note: See TracChangeset for help on using the changeset viewer.