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

Last change on this file since 29170 was 29170, checked in by ak19, 10 years ago

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

File size: 21.5 KB
RevLine 
[24446]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;
[24453]33use solrserver;
[24446]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
[27781]82 my $text_dir = &FileUtils::filenameConcatenate($self->{'build_dir'}, "text");
83 my $build_dir = &FileUtils::filenameConcatenate($self->{'build_dir'},"");
84 &FileUtils::makeAllDirectories($text_dir);
[24446]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 {
[24501]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
[24446]118
[25889]119 $core = "building-".$core unless $self->{'incremental'}; # core points to building only for force_removeold
120
[24446]121 print STDERR "Executable: $solr_passes_exe\n";
122 print STDERR "Sections: $solr_passes_sections\n";
123 print STDERR "Build Dir: $build_dir\n";
[24501]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"))
[24446]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
[27781]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
[24446]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 (@_);
[27781]269
[24446]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'
[27781]279
[24446]280 my $schema_insert_xml = "";
281
282 foreach my $ifm (@{$self->{'build_cfg'}->{'indexfieldmap'}}) {
283
[25846]284 my ($field) = ($ifm =~ m/^.*->(.*)$/);
[24446]285
[25846]286 $schema_insert_xml .= " "; # indent
287 $schema_insert_xml .= "<field name=\"$field\" ";
[24446]288
[25846]289 if($field eq "LA" || $field eq "LO")
290 {
291 $schema_insert_xml .= "type=\"location\" ";
292 }
[27802]293# elsif ($field ne "ZZ" && $field ne "TX")
294# {
295# $schema_insert_xml .= "type=\"string\" ";
296# }
[25846]297 else
298 {
299 $schema_insert_xml .= "type=\"text_en_splitting\" ";
300 }
[29170]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";
[27781]304 $schema_insert_xml .= "indexed=\"true\" stored=\"false\" multiValued=\"true\" />\n";
305 #$schema_insert_xml .= "indexed=\"true\" stored=\"true\" multiValued=\"true\" />\n";
[24446]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'};
[27781]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");
[24446]317
318 my $collect_home = $ENV{'GSDLCOLLECTDIR'};
[27781]319 my $out_dirname = &FileUtils::filenameConcatenate($collect_home,"etc","conf");
320 my $schema_out_filename = &FileUtils::filenameConcatenate($out_dirname,"schema.xml");
[24446]321
322 # make sure output conf directory exists
[29142]323 if (!&FileUtils::directoryExists($out_dirname)) {
[27781]324 &FileUtils::makeDirectory($out_dirname);
[24446]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",
[29142]333 "synonyms.txt", "protwords.txt", "currency.xml", "elevate.xml" );
[24497]334
[24446]335 foreach my $file ( @in_file_list ) {
[27781]336 my $in_filename = &FileUtils::filenameConcatenate($in_dirname,$file.".in");
337 my $out_filename = &FileUtils::filenameConcatenate($out_dirname,$file);
[29142]338
339 if(&FileUtils::fileExists($in_filename)) {
340 filter_in_out_file($in_filename,$out_filename,[]);
341 }
[24446]342 }
[29142]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 }
[24446]353}
354
355
356sub pre_build_indexes
357{
358 my $self = shift (@_);
359 my ($indexname) = @_;
360 my $outhandle = $self->{'outhandle'};
361
[24453]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
[24501]365 my $solr_server = new solrserver($self->{'build_dir'});
[24453]366 $solr_server->start();
367 $self->{'solr_server'} = $solr_server;
[24446]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
[27781]382 # Using a hashmap here would avoid duplications, but while more space
[24446]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
[27781]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 }
[24446]448 }
449
[24453]450 # Write out solr 'schema.xml' (and related) file
451 #
[24446]452 $self->make_final_field_list();
453 $self->premake_solr_auxiliary_files();
454
[24453]455 # Now update the solr-core information in solr.xml
456 # => at most two cores <colname>-Doc and <colname>-Sec
[24446]457
[24501]458 my $site = $self->{'site'};
459 my $collect = $self->{'collection'};
460 my $core_prefix = (defined $site) ? "$site-$collect" : $collect;
[24453]461
[24456]462 # my $idx = $self->{'index_mapping'}->{$index};
463 my $idx = "idx";
464
[24501]465 my $build_dir = $self->{'build_dir'};
[24497]466
[24453]467 foreach my $level (keys %{$self->{'levels'}}) {
[24456]468
469 my ($pindex) = $level =~ /^(.)/;
[24483]470
[24501]471 my $index_dir = $pindex.$idx;
472 my $core = "$core_prefix-$index_dir";
[24497]473
[24643]474 # force_removeold == opposite of being run in 'incremental' mode
[24501]475 my $force_removeold = ($self->{'incremental'}) ? 0 : 1;
[24643]476
[24501]477 if ($force_removeold) {
478 print $outhandle "\n-removeold set (new index will be created)\n";
479
[25889]480 # create cores under temporary core names, corresponding to building directory
481 $core = "building-".$core;
482
[27781]483 my $full_index_dir = &FileUtils::filenameConcatenate($build_dir,$index_dir);
484 &FileUtils::removeFilesRecursive($full_index_dir);
485 &FileUtils::makeDirectory($full_index_dir);
[24643]486
[29142]487 my $full_tlog_dir = &FileUtils::filenameConcatenate($full_index_dir, "tlog");
488 &FileUtils::makeDirectory($full_tlog_dir);
489
[24643]490 # Solr then wants an "index" folder within this general index area!
[27781]491# my $full_index_index_dir = &FileUtils::filenameConcatenate($full_index_dir,"index");
492# &FileUtils::makeDirectory($full_index_index_dir);
[24643]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
[24501]499 }
[24643]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
[24483]506
[24643]507 my $check_core_exists = $solr_server->admin_ping_core($core);
[24483]508
[24643]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 }
[24456]517 }
[24453]518 }
519
[24446]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};
[27781]533 &FileUtils::makeAllDirectories(&FileUtils::filenameConcatenate($build_dir, $indexdir));
[24446]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 {
[24501]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";
[24446]603
[25889]604 $core = "building-".$core unless $self->{'incremental'}; # core points to building only for force_removeold
605
[24501]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")) {
[24446]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);
[27802]636 if (defined $self->{'collect_cfg'}->{'sortfields'}) {
637 $self->{'buildproc'}->set_sortfields ($self->{'collect_cfg'}->{'sortfields'});
638 }
[27815]639 if (defined $self->{'collect_cfg'}->{'facetfields'}) {
640 $self->{'buildproc'}->set_facetfields ($self->{'collect_cfg'}->{'facetfields'});
641 }
[24446]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'});
[25846]649
[24446]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
[24453]668
669
670 # Also need to stop the Solr/jetty server if it was explicitly started
671 # in pre_build_indexes()
[24446]672
[24453]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
[24446]681}
682
[27815]683sub build_cfg_extra {
684 my $self = shift (@_);
685 my ($build_cfg) = @_;
[24446]686
[27815]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}
[24446]7061;
707
708
Note: See TracBrowser for help on using the repository browser.