# Values from grouped fields are copied into the group field.
# Here we make some assumptions about the general purpose of
# each group.
+ # The 'keyword' variation of each is used for exact matches,
+ # starts with, and similar searches.
# Note the ignore_above only affects the 'keyword' version of the
# field, the assumption being text that large would solely be
# searched via 'text' indexes.
},
keyword => {
# term (aka "keyword") searches are not used on the
- # keyword field, but we index it just the same (sans lowercase)
- # for structural consistency with other group fields.
+ # keyword field, but we structure the index just the same
+ # for consistency with other group fields.
type => 'keyword',
- ignore_above => $IGNORE_ABOVE,
+ ignore_above => 1, # essentially a no-op.
fields => {
text => {type => 'text'},
text_folded => {type => 'text', analyzer => 'folding'},
text_stripdots => {type => 'text', analyzer => 'stripdots'}
}
},
+ # Identifier fields only support 'keyword' indexes, no full-text.
identifier => {
- # Avoid full-text indexing on identifier fields.
type => 'keyword',
ignore_above => $IGNORE_ABOVE,
normalizer => 'custom_lowercase',
- },
+ }
};
-my %SHORT_GROUP_MAP = (
- title => 'ti',
- author => 'au',
- subject => 'su',
- series => 'se',
- keyword => 'kw',
- identifier => 'id'
+# Create aliases so users can user for 'author' with 'au', etc.
+my %SEARCH_CLASS_ALIAS_MAP = (
+ ti => 'title.text',
+ au => 'author.text',
+ su => 'subject.text',
+ se => 'series.text',
+ kw => 'keyword.text',
+ id => 'identifier'
);
sub index_class {
@seen_fields = (); # reset with each run
+ # Apply the transform in "target=index-fields" mode to extract just
+ # the field definitions.
my $null_doc = XML::LibXML->load_xml(string => '<root/>');
my $result = $self->xsl_sheet->transform($null_doc, target => '"index-fields"');
my $output = $self->xsl_sheet->output_as_chars($result);
}
my $marc_doc = XML::LibXML->load_xml(string => $db_rec->{marc});
- my $result = $self->xsl_sheet->transform($marc_doc, target => '"index-values"');
+ my $result =
+ $self->xsl_sheet->transform($marc_doc, target => '"index-values"');
my $output = $self->xsl_sheet->output_as_chars($result);
my @rows = split(/\n/, $output);
# Now that we've added the static (and dynamic) fields,
# add the shortened field_class aliases.
- while (my ($field, $alias) = each %SHORT_GROUP_MAP) {
+ while (my ($alias, $field) = each %SEARCH_CLASS_ALIAS_MAP) {
return 0 unless $self->create_one_field_index(
$alias, {type => 'alias', path => $field});
}
use OpenILS::Utils::Fieldmapper;
use OpenILS::Utils::CStoreEditor;
use OpenILS::Elastic::BibSearch;
-use OpenILS::Elastic::BibSearch::XSLT;
my $help;
my $osrf_config = '/openils/conf/opensrf_core.xml';
version="1.0">
<xsl:output encoding="UTF-8" method="text"/>
- <!--
+ <!--
+
+ XSLT for transforming bib records into indexable fields / data
+ suitable for consumption by the Elasticsearch BibSearch indexer.
+
+ TRANSFORM REQUIREMENTS ===
+
Transform operates in one of two modes:
1. target == 'index-fields'
search subject topic South America
facet author personal Janey Jam "Jojo" Jones
+
+ INDEX REQUIREMENTS ===
+
+ For searches, the index name can be anything, but all indexes must
+ use one of the following search classes:
+
+ title
+ author
+ subject
+ series
+ keyword
+ identifier
+
+ Required Filters for Bib Transform Based on Staff Catalog Options
+ at Time of Writing:
+
+ item_type
+ item_form
+ item_lang
+ audience
+ vr_format
+ bib_level
+ lit_form
+ search_format
-->
<xsl:template match="@*|node()">
</xsl:template>
<xsl:template name="compile_sorters">
-
+
<!-- author sort is the first 1XX value -->
<xsl:for-each select="marc:datafield[starts-with(@tag, '1')]">
<xsl:sort select="@tag"/>
</xsl:template>
<xsl:template name="compile_filters">
-
+
<!-- start with filters that are not used within composite filters.
These can be added to the document inline. -->
<xsl:call-template name="add_filter_entry">
</xsl:with-param>
</xsl:call-template>
- <!-- Filters that may be used within composite filters are
+ <!-- Filters that may be used within composite filters are
stored in a local variable so they can first be added
to the document, then used to compile composite filters -->
<xsl:with-param name="name">vr_format</xsl:with-param>
<xsl:with-param name="value" select="$vr_format" />
</xsl:call-template>
-
+
<xsl:variable name="sr_format">
<xsl:if test="$category_of_material = 's'">
<xsl:call-template name="controlfield_value">
<xsl:with-param name="name">sr_format</xsl:with-param>
<xsl:with-param name="value" select="$sr_format" />
</xsl:call-template>
-
+
<!-- use the extracted raw filters to create composite filters -->
<xsl:call-template name="add_composite_filter_entry">
<xsl:param name="sr_format_codes"/>
<xsl:variable name="item_type_matches" select="
- not($item_type_codes) or (
+ not($item_type_codes) or (
$item_type != '' and
contains($item_type_codes, $item_type)
- )
+ )
"/>
<xsl:variable name="item_form_matches" select="
(
- not($item_form_codes) or
+ not($item_form_codes) or
contains($item_form_codes, $item_form)
) and (
not($item_form_not_codes) or
<xsl:variable name="vr_format_matches" select="
not($vr_format_codes) or (
- $vr_format != '' and
+ $vr_format != '' and
contains($vr_format_codes, $vr_format)
)
"/>
<xsl:if test="
$target = 'index-fields' or (
- $item_type_matches and
- $item_form_matches and
+ $item_type_matches and
+ $item_form_matches and
$bib_level_matches and
$sr_format_matches and
$vr_format_matches
</xsl:if>
</xsl:template>
- <!-- Dumps practically the entire document into a single
+ <!-- Dumps practically the entire document into a single
keyword|keyword index.
-->
<xsl:template name="keyword_full_entry">