View | Details | Raw Unified | Return to bug 11232
Collapse All | Expand All

(-)a/C4/Search.pm (-26 / +143 lines)
Lines 343-349 sub getRecords { Link Here
343
    my $facets_counter = {};
343
    my $facets_counter = {};
344
    my $facets_info    = {};
344
    my $facets_info    = {};
345
    my $facets         = getFacets();
345
    my $facets         = getFacets();
346
    my $facets_maxrecs = C4::Context->preference('maxRecordsForFacets')||20;
347
346
348
    my @facets_loop;    # stores the ref to array of hashes for template facets loop
347
    my @facets_loop;    # stores the ref to array of hashes for template facets loop
349
348
Lines 502-533 sub getRecords { Link Here
502
                # Fill the facets while we're looping, but only for the
501
                # Fill the facets while we're looping, but only for the
503
                # biblioserver and not for a scan
502
                # biblioserver and not for a scan
504
                if ( !$scan && $servers[ $i - 1 ] =~ /biblioserver/ ) {
503
                if ( !$scan && $servers[ $i - 1 ] =~ /biblioserver/ ) {
505
504
                    $facets_counter = GetFacets( $results[ $i - 1 ] );
506
                    my $jmax = $size > $facets_maxrecs
505
                    $facets_info    = _get_facets_info( $facets );
507
                                ? $facets_maxrecs
508
                                : $size;
509
510
                    for ( my $j = 0 ; $j < $jmax ; $j++ ) {
511
512
                        my $marc_record = new_record_from_zebra (
513
                                'biblioserver',
514
                                $results[ $i - 1 ]->record($j)->raw()
515
                        );
516
517
                        if ( ! defined $marc_record ) {
518
                            warn "ERROR DECODING RECORD - $@: " .
519
                                $results[ $i - 1 ]->record($j)->raw();
520
                            next;
521
                        }
522
523
                        _get_facets_data_from_record( $marc_record, $facets, $facets_counter );
524
                        $facets_info = _get_facets_info( $facets );
525
                    }
526
                }
506
                }
527
507
528
                # warn "connection ", $i-1, ": $size hits";
529
                # warn $results[$i-1]->record(0)->render() if $size > 0;
530
531
                # BUILD FACETS
508
                # BUILD FACETS
532
                if ( $servers[ $i - 1 ] =~ /biblioserver/ ) {
509
                if ( $servers[ $i - 1 ] =~ /biblioserver/ ) {
533
                    for my $link_value (
510
                    for my $link_value (
Lines 652-657 sub getRecords { Link Here
652
    return ( undef, $results_hashref, \@facets_loop );
629
    return ( undef, $results_hashref, \@facets_loop );
653
}
630
}
654
631
632
sub GetFacets {
633
634
    my $rs = shift;
635
    my $facets;
636
637
    my $index_mode = C4::Context->config('zebra_auth_index_mode') // 'dom';
638
639
    if ( $index_mode eq 'dom' ) {
640
        $facets = _get_facets_from_zebra( $rs );
641
    } else {
642
        $facets = _get_facets_from_records( $rs );
643
    }
644
645
    return $facets;
646
}
647
648
sub _get_facets_from_records {
649
650
    my $rs = shift;
651
652
    my $facets_maxrecs = C4::Context->preference('maxRecordsForFacets') // 20;
653
    my $facets_config  = getFacets();
654
    my $facets         = {};
655
    my $size           = $rs->size();
656
    my $jmax           = $size > $facets_maxrecs
657
                            ? $facets_maxrecs
658
                            : $size;
659
660
    for ( my $j = 0 ; $j < $jmax ; $j++ ) {
661
662
        my $marc_record = new_record_from_zebra (
663
                'biblioserver',
664
                $rs->record( $j )->raw()
665
        );
666
667
        if ( ! defined $marc_record ) {
668
            warn "ERROR DECODING RECORD - $@: " .
669
                $rs->record( $j )->raw();
670
            next;
671
        }
672
673
        _get_facets_data_from_record( $marc_record, $facets_config, $facets );
674
    }
675
676
    return $facets;
677
}
678
655
=head2 _get_facets_data_from_record
679
=head2 _get_facets_data_from_record
656
680
657
    C4::Search::_get_facets_data_from_record( $marc_record, $facets, $facets_counter );
681
    C4::Search::_get_facets_data_from_record( $marc_record, $facets, $facets_counter );
Lines 696-701 sub _get_facets_data_from_record { Link Here
696
    }
720
    }
697
}
721
}
698
722
723
=head2 _get_facets_from_zebra
724
725
    my $facets = _get_facets_from_zebra( $result_set )
726
727
Retrieves facets for a specified result set. It loops through the facets defined
728
in C4::Koha::getFacets and returns a hash with the following structure:
729
730
   {  facet_idx => {
731
            facet_value => count
732
      },
733
      ...
734
   }
735
736
=cut
737
738
sub _get_facets_from_zebra {
739
740
    my $rs = shift;
741
742
    # save current elementSetName
743
    my $elementSetName = $rs->option( 'elementSetName' );
744
745
    my $facets_loop = getFacets();
746
    my $facets_data  = {};
747
    # loop through defined facets and fill the facets hashref
748
    foreach my $facet ( @$facets_loop ) {
749
750
        my $idx = $facet->{ idx };
751
        my $sep = $facet->{ sep };
752
        my $facet_values = _get_facet_from_result_set( $idx, $rs, $sep );
753
        if ( $facet_values ) {
754
            # we've actually got a result
755
            $facets_data->{ $idx } = $facet_values;
756
        }
757
    }
758
    # set elementSetName to its previous value to avoid side effects
759
    $rs->option( elementSetName => $elementSetName );
760
761
    return $facets_data;
762
}
763
764
=head2 _get_facet_from_result_set
765
766
    my $facet_values =
767
        C4::Search::_get_facet_from_result_set( $facet_idx, $result_set, $sep )
768
769
Internal function that extracts facet information for a specific index ($facet_idx) and
770
returns a hash containing facet values and count:
771
772
    {
773
        $facet_value => $count ,
774
        ...
775
    }
776
777
Warning: this function has the side effect of changing the elementSetName for the result
778
set. It is a helper function for the main loop, which takes care of backing it up for
779
restoring.
780
781
=cut
782
783
sub _get_facet_from_result_set {
784
785
    my $facet_idx = shift;
786
    my $rs        = shift;
787
    my $sep       = shift;
788
789
    my $internal_sep = '<*>';
790
791
    return if ( ! defined $facet_idx || ! defined $rs );
792
    # zebra's facet element, untokenized index
793
    my $facet_element = 'zebra::facet::' . $facet_idx . ':0:100';
794
    # configure zebra results for retrieving the desired facet
795
    $rs->option( elementSetName => $facet_element );
796
    # get the facet record from result set
797
    my $facet = $rs->record( 0 )->raw;
798
    # if the facet has no restuls...
799
    return if !defined $facet;
800
    # TODO: benchmark DOM vs. SAX performance
801
    my $facet_dom = XML::LibXML->load_xml(
802
      string => ($facet)
803
    );
804
    my @terms = $facet_dom->getElementsByTagName('term');
805
    return if ! @terms;
806
807
    my $facets = {};
808
    foreach my $term ( @terms ) {
809
        my $facet_value = $term->textContent;
810
        $facet_value =~ s/\Q$internal_sep\E/$sep/ if defined $sep;
811
        $facets->{ $facet_value } = $term->getAttribute( 'occur' );
812
    }
813
814
    return $facets;
815
}
816
699
=head2 _get_facets_info
817
=head2 _get_facets_info
700
818
701
    my $facets_info = C4::Search::_get_facets_info( $facets )
819
    my $facets_info = C4::Search::_get_facets_info( $facets )
702
- 

Return to bug 11232