root/gs3-extensions/solr/trunk/src/perllib/solrbuilder.pm @ 29170

Revision 29170, 21.5 KB (checked in by ak19, 5 years ago)

TotalTermFrequency? is now calculated for each search term in the query string

Line 
1###########################################################################
2#
3# solrbuilder.pm -- perl wrapper for building index with Solr
4# A component of the Greenstone digital library software
5# from the New Zealand Digital Library Project at the
6# University of Waikato, New Zealand.
7#
8# Copyright (C) 1999 New Zealand Digital Library Project
9#
10# This program is free software; you can redistribute it and/or modify
11# it under the terms of the GNU General Public License as published by
12# the Free Software Foundation; either version 2 of the License, or
13# (at your option) any later version.
14#
15# This program is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18# GNU General Public License for more details.
19#
20# You should have received a copy of the GNU General Public License
21# along with this program; if not, write to the Free Software
22# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23#
24###########################################################################
25
26
27package solrbuilder;
28
29use strict;
30no strict 'refs';
31
32use lucenebuilder;
33use solrserver;
34use Config; # for getting the perlpath in the recommended way
35
36sub BEGIN {
37    @solrbuilder::ISA = ('lucenebuilder');
38}
39
40
41sub new {
42    my $class = shift(@_);
43    my $self = new lucenebuilder (@_);
44    $self = bless $self, $class;
45
46    $self->{'buildtype'} = "solr";
47
48    my $solr_passes_script = "solr_passes.pl";
49
50    $self->{'solr_passes'} = "$solr_passes_script";
51    # Tack perl on the beginning to ensure execution
52    $self->{'solr_passes_exe'} = "\"$Config{perlpath}\" -S \"$solr_passes_script\"";
53    return $self;
54}
55
56
57sub default_buildproc {
58    my $self  = shift (@_);
59
60    return "solrbuildproc";
61}
62
63# This writes a nice version of the text docs
64#
65# Essentially the same as the lucenebuilder.pm version, only using solr_passes
66# => refactor and make better use of inheritence
67#
68sub compress_text
69{
70    my $self = shift (@_);
71    # do nothing if we don't want compressed text
72    return if $self->{'no_text'};
73
74    my ($textindex) = @_;
75
76    # workaround to avoid hard-coding "solr" check into buildcol.pl
77    $textindex =~ s/^section://;
78
79    my $outhandle = $self->{'outhandle'};
80
81    # the text directory
82    my $text_dir = &FileUtils::filenameConcatenate($self->{'build_dir'}, "text");
83    my $build_dir = &FileUtils::filenameConcatenate($self->{'build_dir'},"");
84    &FileUtils::makeAllDirectories($text_dir);
85
86    my $osextra = "";
87    if ($ENV{'GSDLOS'} =~ /^windows$/i)
88    {
89    $text_dir =~ s@/@\\@g;
90    }
91    else
92    {
93    if ($outhandle ne "STDERR")
94    {
95        # so solr_passes doesn't print to stderr if we redirect output
96        $osextra .= " 2>/dev/null";
97    }
98    }
99
100    # Find the perl script to call to run solr
101    my $solr_passes = $self->{'solr_passes'};
102    my $solr_passes_exe = $self->{'solr_passes_exe'};
103
104    my $solr_passes_sections = "Doc";
105
106    my ($handle);
107
108    if ($self->{'debug'})
109    {
110    $handle = *STDOUT;
111    }
112    else
113    {
114    my $site        = $self->{'site'};
115    my $collect     = $self->{'collection'};   
116    my $core_prefix = (defined $site) ? "$site-$collect" : $collect;
117    my $core        = $core_prefix; # unused in this call to solr_passes
118
119    $core = "building-".$core unless $self->{'incremental'}; # core points to building only for force_removeold
120
121        print STDERR "Executable:    $solr_passes_exe\n";
122        print STDERR "Sections:      $solr_passes_sections\n";
123        print STDERR "Build Dir:     $build_dir\n";
124        print STDERR "Cmd:           $solr_passes_exe $core text \"$build_dir\" \"dummy\"   $osextra\n";
125    if (!open($handle, "| $solr_passes_exe $core text \"$build_dir\" \"dummy\"   $osextra"))
126    {
127        print STDERR "<FatalError name='NoRunSolrPasses'/>\n</Stage>\n" if $self->{'gli'};
128        die "solrbuilder::build_index - couldn't run $solr_passes_exe\n$!\n";
129    }
130    }
131
132    # stored text is always Doc and Sec levels   
133    my $levels = { 'document' => 1, 'section' => 1 };
134    # always do database at section level
135    my $db_level = "section";
136
137    # set up the document processr
138    $self->{'buildproc'}->set_output_handle ($handle);
139    $self->{'buildproc'}->set_mode ('text');
140    $self->{'buildproc'}->set_index ($textindex);
141    $self->{'buildproc'}->set_indexing_text (0);
142    #$self->{'buildproc'}->set_indexfieldmap ($self->{'indexfieldmap'});
143    $self->{'buildproc'}->set_levels ($levels);
144    $self->{'buildproc'}->set_db_level ($db_level);
145    $self->{'buildproc'}->reset();
146
147    &plugin::begin($self->{'pluginfo'}, $self->{'source_dir'},
148           $self->{'buildproc'}, $self->{'maxdocs'});
149    &plugin::read ($self->{'pluginfo'}, $self->{'source_dir'},
150           "", {}, {}, $self->{'buildproc'}, $self->{'maxdocs'}, 0, $self->{'gli'});
151    &plugin::end($self->{'pluginfo'});
152
153    close ($handle) unless $self->{'debug'};
154    $self->print_stats();
155
156    print STDERR "</Stage>\n" if $self->{'gli'};
157}
158
159#----
160
161
162
163sub filter_in_out_file
164{
165    my ($in_filename,$out_filename,$replace_rules) = @_;
166
167    if (open(SIN,"<$in_filename")) {
168
169    if (open(SOUT,">$out_filename")) {
170
171        my $line;
172        while (defined ($line=<SIN>)) {
173        chomp $line;
174
175        my $done_insert = 0;
176        foreach my $rule (@$replace_rules) {
177            my $line_re = $rule->{'regexp'};
178            my $insert  = $rule->{'insert'};
179
180            if ($line =~ m/$line_re/) {
181            print SOUT $insert;
182            $done_insert = 1;
183            last;
184            }
185        }
186        if (!$done_insert) {
187            print SOUT "$line\n";;
188        }
189        }
190
191        close(SOUT);
192    }
193    else {
194        print STDERR "Error: Failed to open $out_filename\n";
195        print STDERR "       $!\n";
196    }
197
198    close(SIN);
199    }
200    else {
201    print STDERR "Error: Failed to open $in_filename\n";
202    print STDERR "       $!\n";
203    }
204
205}
206
207# We need to push the list of indexfield to shortname mappings through to the
208# build_cfg as, unlike in MGPP, we need these mappings in advance to configure
209# Lucene/Solr. Unfortunately the original function found in mgbuilder.pm makes
210# a mess of this - it only output fields that have been processed (none have)
211# and it has a hardcoded renaming for 'text' so it becomes 'TX' according to
212# the schema but 'TE' according to XML sent to lucene_passes.pl/solr_passes.pl
213# This version is dumber - just copy them all across verbatum - but works. We
214# do still need to support the special case of 'allfields'
215sub make_final_field_list
216{
217  my $self = shift (@_);
218  $self->{'build_cfg'} = {};
219  my @indexfieldmap = ();
220  my @indexfields = ();
221
222  # @todo support: $self->{'buildproc'}->{'extraindexfields'}
223  foreach my $fields (@{$self->{'collect_cfg'}->{'indexes'}})
224  {
225    # remove subcoll stuff
226    $fields =~ s/:.*$//;
227    foreach my $field (split(';', $fields))
228    {
229      my $shortname = 'ERROR';
230      if ($field eq 'allfields')
231      {
232        $shortname = 'ZZ';
233      }
234      elsif (defined $self->{'buildproc'}->{'indexfieldmap'}->{$field})
235      {
236        $shortname = $self->{'buildproc'}->{'indexfieldmap'}->{$field};
237      }
238      else
239      {
240        print STDERR 'Error! Couldn\'t find indexfieldmap for field: ' . $field . "\n";
241      }
242      push (@indexfieldmap, $field . '->' . $shortname);
243      push (@indexfields, $field);
244    }
245  }
246
247  if (scalar @indexfieldmap)
248  {
249    $self->{'build_cfg'}->{'indexfieldmap'} = \@indexfieldmap;
250  }
251
252  if (scalar @indexfields)
253  {
254    $self->{'build_cfg'}->{'indexfields'} = \@indexfields;
255  }
256}
257
258# Generate solr schema.xml file based on indexmapfield and other associated
259# config files
260#
261# Unlike make_auxiliary_files(), this needs to be done up-front (rather
262# than at the end) so the data-types in schema.xml are correctly set up
263# prior to document content being pumped through solr_passes.pl
264
265
266sub premake_solr_auxiliary_files
267{
268    my $self = shift (@_);
269
270    # Replace the following marker:
271    #
272    #   <!-- ##GREENSTONE-FIELDS## -->
273    #
274    # with lines of the form:
275    #
276    #   <field name="<field>" type="string" ... />
277    #
278    # for each <field> in 'indexfieldmap'
279
280    my $schema_insert_xml = "";
281
282    foreach my $ifm (@{$self->{'build_cfg'}->{'indexfieldmap'}}) {
283
284        my ($field) = ($ifm =~ m/^.*->(.*)$/);
285
286        $schema_insert_xml .= "    "; # indent
287        $schema_insert_xml .= "<field name=\"$field\" ";
288
289        if($field eq "LA" || $field eq "LO")
290        {
291            $schema_insert_xml .=   "type=\"location\" ";
292        }
293#       elsif ($field ne "ZZ" && $field ne "TX")
294#       {
295#           $schema_insert_xml .=   "type=\"string\" ";
296#       }
297        else
298        {
299            $schema_insert_xml .= "type=\"text_en_splitting\" ";
300        }
301        # set termVectors=\"true\" when term vectors info is required,
302        # see TermsResponse termResponse = solrResponse.getTermsResponse();
303        #$schema_insert_xml .=  "indexed=\"true\" stored=\"false\" termVectors=\"true\" multiValued=\"true\" />\n";
304        $schema_insert_xml .=  "indexed=\"true\" stored=\"false\" multiValued=\"true\" />\n";
305                #$schema_insert_xml .=  "indexed=\"true\" stored=\"true\" multiValued=\"true\" />\n";
306    }
307
308    # just the one rule to date
309    my $insert_rules
310    = [ { 'regexp' => "^\\s*<!--\\s*##GREENSTONE-FIELDS##\\s*-->\\s*\$",
311          'insert' => $schema_insert_xml } ];
312       
313    my $solr_home = $ENV{'GEXT_SOLR'};
314##    my $in_dirname = &FileUtils::filenameConcatenate($solr_home,"etc","conf");
315    my $in_dirname = &FileUtils::filenameConcatenate($solr_home,"conf");
316    my $schema_in_filename = &FileUtils::filenameConcatenate($in_dirname,"schema.xml.in");
317
318    my $collect_home = $ENV{'GSDLCOLLECTDIR'};
319    my $out_dirname = &FileUtils::filenameConcatenate($collect_home,"etc","conf");
320    my $schema_out_filename = &FileUtils::filenameConcatenate($out_dirname,"schema.xml");
321   
322    # make sure output conf directory exists
323    if (!&FileUtils::directoryExists($out_dirname)) {
324    &FileUtils::makeDirectory($out_dirname);
325    }
326
327    filter_in_out_file($schema_in_filename,$schema_out_filename,$insert_rules);
328
329    # now do the same for solrconfig.xml, stopwords, ...
330    # these are simpler, as they currently do not need any filtering
331
332    my @in_file_list = ( "solrconfig.xml", "stopwords.txt", "stopwords_en.txt",
333             "synonyms.txt", "protwords.txt", "currency.xml", "elevate.xml" );
334 
335    foreach my $file ( @in_file_list ) {
336    my $in_filename = &FileUtils::filenameConcatenate($in_dirname,$file.".in");
337    my $out_filename = &FileUtils::filenameConcatenate($out_dirname,$file);
338
339    if(&FileUtils::fileExists($in_filename)) {
340        filter_in_out_file($in_filename,$out_filename,[]);
341    }
342    }
343
344    my @in_dir_list = ( "lang" );
345    foreach my $dir ( @in_dir_list ) {
346   
347    my $full_subdir_name = &FileUtils::filenameConcatenate($in_dirname,$dir);
348
349    if(&FileUtils::directoryExists($full_subdir_name)) {
350        &FileUtils::copyFilesRecursiveNoSVN($full_subdir_name, $out_dirname);
351    }
352    }
353}
354
355
356sub pre_build_indexes
357{
358    my $self = shift (@_);
359    my ($indexname) = @_;
360    my $outhandle = $self->{'outhandle'};
361
362    # If the Solr/Jetty server is not already running, the following starts
363    # it up, and only returns when the server is "reading and listening"
364 
365    my $solr_server = new solrserver($self->{'build_dir'});
366    $solr_server->start();
367    $self->{'solr_server'} = $solr_server;
368
369    my $indexes = [];
370    if (defined $indexname && $indexname =~ /\w/) {
371    push @$indexes, $indexname;
372    } else {
373    $indexes = $self->{'collect_cfg'}->{'indexes'};
374    }
375
376    # skip para-level check, as this is done in the main 'build_indexes'
377    # routine
378
379    my $all_metadata_specified = 0; # has the user added a 'metadata' index?
380    my $allfields_index = 0;        # do we have an allfields index?
381
382    # Using a hashmap here would avoid duplications, but while more space
383    # efficient, it's not entirely clear it would be more computationally
384    # efficient
385    my @all_fields = ();
386
387    foreach my $index (@$indexes) {
388    if ($self->want_built($index)) {
389
390        # get the parameters for the output
391        # split on : just in case there is subcoll and lang stuff
392        my ($fields) = split (/:/, $index);
393
394        foreach my $field (split (/;/, $fields)) {
395        if ($field eq "metadata") {
396            $all_metadata_specified = 1;
397        }
398        else {
399            push(@all_fields,$field);
400        }
401        }
402    }
403    }
404
405    if ($all_metadata_specified) {
406
407    # (Unforunately) we need to process all the documents in the collection
408    # to figure out what the metadata_field_mapping is     
409
410    # set up the document processr
411    $self->{'buildproc'}->set_output_handle (undef);
412    $self->{'buildproc'}->set_mode ('index_field_mapping');
413    $self->{'buildproc'}->reset();
414   
415    &plugin::begin($self->{'pluginfo'}, $self->{'source_dir'},
416               $self->{'buildproc'}, $self->{'maxdocs'});
417    &plugin::read ($self->{'pluginfo'}, $self->{'source_dir'},
418               "", {}, {}, $self->{'buildproc'}, $self->{'maxdocs'}, 0, $self->{'gli'});
419    &plugin::end($self->{'pluginfo'});
420   
421    }
422
423    else {
424    # Field mapping solely dependent of entries in 'indexes'
425
426    # No need to explicitly handle "allfields" as create_shortname()
427    # will get a fix on it through it's static_indexfield_map
428
429    my $buildproc = $self->{'buildproc'};
430   
431      foreach my $field (@all_fields)
432      {
433        if (!defined $buildproc->{'indexfieldmap'}->{$field})
434        {
435          my $shortname = '';
436          if (defined $buildproc->{'fieldnamemap'}->{$field})
437          {
438            $shortname = $buildproc->{'fieldnamemap'}->{$field};
439          }
440          else
441          {
442            $shortname = $buildproc->create_shortname($field);
443          }
444          $buildproc->{'indexfieldmap'}->{$field} = $shortname;
445          $buildproc->{'indexfieldmap'}->{$shortname} = 1;
446        }
447      }
448    }
449
450    # Write out solr 'schema.xml' (and related) file
451    #
452    $self->make_final_field_list();
453    $self->premake_solr_auxiliary_files();
454
455    # Now update the solr-core information in solr.xml
456    # => at most two cores <colname>-Doc and <colname>-Sec
457
458    my $site        = $self->{'site'};
459    my $collect     = $self->{'collection'};
460    my $core_prefix = (defined $site) ? "$site-$collect" : $collect;
461
462    # my $idx = $self->{'index_mapping'}->{$index};
463    my $idx = "idx";
464
465    my $build_dir = $self->{'build_dir'};
466
467    foreach my $level (keys %{$self->{'levels'}}) {
468   
469    my ($pindex) = $level =~ /^(.)/;
470
471    my $index_dir = $pindex.$idx;
472    my $core = "$core_prefix-$index_dir";
473
474    # force_removeold == opposite of being run in 'incremental' mode
475    my $force_removeold = ($self->{'incremental'}) ? 0 : 1;
476
477    if ($force_removeold) {
478        print $outhandle "\n-removeold set (new index will be created)\n";
479
480        # create cores under temporary core names, corresponding to building directory
481        $core = "building-".$core;
482
483        my $full_index_dir = &FileUtils::filenameConcatenate($build_dir,$index_dir);
484        &FileUtils::removeFilesRecursive($full_index_dir);
485        &FileUtils::makeDirectory($full_index_dir);
486
487        my $full_tlog_dir = &FileUtils::filenameConcatenate($full_index_dir, "tlog");
488        &FileUtils::makeDirectory($full_tlog_dir);
489
490        # Solr then wants an "index" folder within this general index area!
491#       my $full_index_index_dir = &FileUtils::filenameConcatenate($full_index_dir,"index");
492#       &FileUtils::makeDirectory($full_index_index_dir);
493
494
495        # now go on and create new index
496        print $outhandle "Creating Solr core: $core\n";
497        $solr_server->admin_create_core($core);
498
499    }
500    else {
501        # if collect==core already in solr.xml (check with STATUS)
502        # => use RELOAD call to refresh fields now expressed in schema.xml
503        #
504        # else
505        # => use CREATE API to add to solr.xml
506       
507        my $check_core_exists = $solr_server->admin_ping_core($core);
508       
509        if ($check_core_exists) {       
510        print $outhandle "Reloading Solr core: $core\n";
511        $solr_server->admin_reload_core($core);
512        }
513        else {
514        print $outhandle "Creating Solr core: $core\n";
515        $solr_server->admin_create_core($core);
516        }
517    }
518    }
519
520}
521
522# Essentially the same as the lucenebuilder.pm version, only using solr_passes
523# => refactor and make better use of inheritence
524
525sub build_index {
526    my $self = shift (@_);
527    my ($index,$llevel) = @_;
528    my $outhandle = $self->{'outhandle'};
529    my $build_dir = $self->{'build_dir'};
530
531    # get the full index directory path and make sure it exists
532    my $indexdir = $self->{'index_mapping'}->{$index};
533    &FileUtils::makeAllDirectories(&FileUtils::filenameConcatenate($build_dir, $indexdir));
534
535    # Find the perl script to call to run solr
536    my $solr_passes = $self->{'solr_passes'};
537    my $solr_passes_exe = $self->{'solr_passes_exe'};
538
539    # define the section names for solrpasses
540    # define the section names and possibly the doc name for solrpasses
541    my $solr_passes_sections = $llevel;
542
543    my $osextra = "";
544    if ($ENV{'GSDLOS'} =~ /^windows$/i) {
545    $build_dir =~ s@/@\\@g;
546    } else {
547    if ($outhandle ne "STDERR") {
548        # so solr_passes doesn't print to stderr if we redirect output
549        $osextra .= " 2>/dev/null";
550    }
551    }
552
553    # get the index expression if this index belongs
554    # to a subcollection
555    my $indexexparr = [];
556    my $langarr = [];
557
558    # there may be subcollection info, and language info.
559    my ($fields, $subcollection, $language) = split (":", $index);
560    my @subcollections = ();
561    @subcollections = split /,/, $subcollection if (defined $subcollection);
562
563    foreach $subcollection (@subcollections) {
564    if (defined ($self->{'collect_cfg'}->{'subcollection'}->{$subcollection})) {
565        push (@$indexexparr, $self->{'collect_cfg'}->{'subcollection'}->{$subcollection});
566    }
567    }
568
569    # add expressions for languages if this index belongs to
570    # a language subcollection - only put languages expressions for the
571    # ones we want in the index
572    my @languages = ();
573    my $languagemetadata = "Language";
574    if (defined ($self->{'collect_cfg'}->{'languagemetadata'})) {
575    $languagemetadata = $self->{'collect_cfg'}->{'languagemetadata'};
576    }
577    @languages = split /,/, $language if (defined $language);
578    foreach my $language (@languages) {
579    my $not=0;
580    if ($language =~ s/^\!//) {
581        $not = 1;
582    }
583    if($not) {
584        push (@$langarr, "!$language");
585    } else {
586        push (@$langarr, "$language");
587    }
588    }
589
590    # Build index dictionary. Uses verbatim stem method
591    print $outhandle "\n    creating index dictionary (solr_passes -I1)\n"  if ($self->{'verbosity'} >= 1);
592    print STDERR "<Phase name='CreatingIndexDic'/>\n" if $self->{'gli'};
593    my ($handle);
594
595    if ($self->{'debug'}) {
596    $handle = *STDOUT;
597    } else {
598    my $site        = $self->{'site'};
599    my $collect     = $self->{'collection'};
600    my $core_prefix = (defined $site) ? "$site-$collect" : $collect;
601    my $ds_idx      = $self->{'index_mapping'}->{$index};
602    my $core        = "$core_prefix-$ds_idx";
603
604    $core = "building-".$core unless $self->{'incremental'}; # core points to building only for force_removeold
605
606    print STDERR "Cmd: $solr_passes_exe $core index \"$build_dir\" \"$indexdir\"   $osextra\n";
607    if (!open($handle, "| $solr_passes_exe $core index \"$build_dir\" \"$indexdir\"   $osextra")) {
608        print STDERR "<FatalError name='NoRunSolrPasses'/>\n</Stage>\n" if $self->{'gli'};
609        die "solrbuilder::build_index - couldn't run $solr_passes_exe\n!$\n";
610    }
611    }
612
613    my $store_levels = $self->{'levels'};
614    my $db_level = "section"; #always
615    my $dom_level = "";
616    foreach my $key (keys %$store_levels) {
617    if ($mgppbuilder::level_map{$key} eq $llevel) {
618        $dom_level = $key;
619    }
620    }
621    if ($dom_level eq "") {
622    print STDERR "Warning: unrecognized tag level $llevel\n";
623    $dom_level = "document";
624    }
625
626    my $local_levels = { $dom_level => 1 }; # work on one level at a time
627
628    # set up the document processr
629    $self->{'buildproc'}->set_output_handle ($handle);
630    $self->{'buildproc'}->set_mode ('text');
631    $self->{'buildproc'}->set_index ($index, $indexexparr);
632    $self->{'buildproc'}->set_index_languages ($languagemetadata, $langarr) if (defined $language);
633    $self->{'buildproc'}->set_indexing_text (1);
634    #$self->{'buildproc'}->set_indexfieldmap ($self->{'indexfieldmap'});
635    $self->{'buildproc'}->set_levels ($local_levels);
636    if (defined $self->{'collect_cfg'}->{'sortfields'}) {
637    $self->{'buildproc'}->set_sortfields ($self->{'collect_cfg'}->{'sortfields'});
638    }
639    if (defined $self->{'collect_cfg'}->{'facetfields'}) {
640    $self->{'buildproc'}->set_facetfields ($self->{'collect_cfg'}->{'facetfields'});
641    }
642    $self->{'buildproc'}->set_db_level($db_level);
643    $self->{'buildproc'}->reset();
644
645    print $handle "<update>\n";
646
647    &plugin::read ($self->{'pluginfo'}, $self->{'source_dir'},
648           "", {}, {}, $self->{'buildproc'}, $self->{'maxdocs'}, 0, $self->{'gli'});
649   
650    print $handle "</update>\n";
651
652    close ($handle) unless $self->{'debug'};
653
654    $self->print_stats();
655
656    $self->{'buildproc'}->set_levels ($store_levels);
657    print STDERR "</Stage>\n" if $self->{'gli'};
658
659}
660
661
662sub post_build_indexes {
663    my $self = shift(@_);
664
665    # deliberately override to prevent the mgpp post_build_index() calling
666    #  $self->make_final_field_list()
667    # as this has been done in our pre_build_indexes() phase for solr
668
669
670    # Also need to stop the Solr/jetty server if it was explicitly started
671    # in pre_build_indexes()
672   
673    my $solr_server = $self->{'solr_server'};
674
675    if ($solr_server->explicitly_started()) {
676    $solr_server->stop();
677    }
678
679    $self->{'solr_server'} = undef;
680
681}   
682
683sub build_cfg_extra {
684    my $self = shift (@_);
685    my ($build_cfg) = @_;
686
687    $self->lucenebuilder::build_cfg_extra($build_cfg);
688
689    # need to add in facet stuff
690    my @facetfields = ();
691    my @facetfieldmap = ();
692
693    foreach my $sf (@{$self->{'buildproc'}->{'facetfields'}}) {
694    if ($sf eq "rank") {
695        push(@facetfields, $sf);
696    } elsif ($self->{'buildproc'}->{'actualsortfields'}->{$sf}) {
697        my $shortname = $self->{'buildproc'}->{'sortfieldnamemap'}->{$sf};
698        push(@facetfields, $shortname);
699        push (@facetfieldmap, "$sf\-\>$shortname");
700    }
701   
702    }
703    $build_cfg->{'indexfacetfields'} = \@facetfields;
704    $build_cfg->{'indexfacetfieldmap'} = \@facetfieldmap;
705
7061;
707
708
Note: See TracBrowser for help on using the browser.