---
# Listing of search types and their component parts and weights.
#
# Format is:
#  searchType:
#    # CustomMunge is an optional section to define custom pre-processing of
#    #     user input when Dismax does not apply.  See below for details of
#    #     munge actions.
#    CustomMunge:
#      MungeName1:
#        - [action1, actionParams]
#        - [action2, actionParams]
#        - [action3, actionParams]
#      MungeName2:
#        - [action1, actionParams]
#    # While CustomMunge only applies to Lucene search, DismaxMunge is a
#    #     counterpart that applies to Dismax and eDismax queries. DismaxMunge
#    #     contains a chain of custom munge operations as described below. Note
#    #     that using this function is NOT RECOMMENDED if you can accomplish your
#    #     goals more elegantly through Solr schema adjustments, but it may be
#    #     useful in some situations, such as when you are connecting to a Solr
#    #     instance that is beyond your direct control. Here is an example stanza:
#    DismaxMunge:
#      - [preg_replace, '/^.*$/', '"$1"']
#    # DismaxFields is optional and defines the fields sent to the Dismax handler
#    #     when we are able to use it.  QueryFields will be used for advanced
#    #     searches that Dismax cannot support.  QueryFields is always used if no
#    #     DismaxFields section is defined.
#    DismaxFields:
#      - field1^boost
#      - field2^boost
#      - field3^boost
#    # DismaxParams is optional and allows you to override default Dismax settings
#    #     (i.e. mm / bf) on a search-by-search basis. Enclose the parameter values
#    #     in quotes for proper behavior. If you want global default values for these
#    #     settings, you can edit the appropriate search handler in
#    #     solr/biblio/conf/solrconfig.xml.
#    DismaxParams:
#      - [param1_name, param1_value]
#      - [param2_name, param2_value]
#      - [param3_name, param3_value]
#    # This optional setting may be used to specify which Dismax handler to use. By
#    #     default, VuFind provides two options: dismax (for the old, standard
#    #     Dismax) and edismax (for Extended Dismax). You can also configure your own
#    #     in solrconfig.xml, but VuFind relies on the name "edismax" to identify an
#    #     Extended Dismax handler. If you omit this setting, the default value from
#    #     the default_dismax_handler setting in the [Index] section of config.ini
#    #     will be used.
#    DismaxHandler: dismax|edismax
#    # QueryFields define the fields we are searching when not using Dismax; VuFind
#    #     detects queries that will not work with Dismax and switches to QueryFields
#    #     as needed.
#    QueryFields:
#      SolrField:
#        - [howToMungeSearchstring, weight]
#        - [differentMunge, weight]
#      DifferentSolrField:
#        - [howToMunge, weight]
#    # The optional FilterQuery section allows you to AND a static query to the
#    #     dynamic query generated using the QueryFields; see JournalTitle below
#    #     for an example.  This is applied whether we use DismaxFields or
#    #     QueryFields.
#    FilterQuery: (optional Lucene filter query)
#    ExactSettings:
#      DismaxFields: ...
#      QueryFields: ...
#    # All the same settings as above, but for exact searches, i.e. search terms
#    #     enclosed in quotes. Allows different fields or weights for exact
#    #     searches. See below for commented-out examples.
#
# ...etc.
#
# GlobalExtraParams allows extra parameters to be (conditionally) added to the Solr
# search request.
#
# Example showcasing all the available conditions:
#
# GlobalExtraParams:
#   - param: bf
#     value: "recip(rord(publishDateSort),1,1000,1000)"
#     conditions:
#       - NoDismaxParams
#         - bf
#         - bq
#       - SearchTypeIn:
#         - AllFields
#         - Title
#         - Author
#       - SearchTypeNotIn:
#         - Series
#
# Value can be a single string or a list of strings to repeat the parameter.
#
# Available conditions:
#
# - NoDismaxParams: None of the search types specifies any of the listed parameters
#   in DismaxParams
# - SearchTypeIn      At least one of the search types must be in the given list
# - AllSearchTypesIn  All of the search types must be in the given list
# - SearchTypeNotIn   None of the search types must be in the given list
# - SortIn            Sort order (exactly as it's sent to Solr) must be in the given list
# - SortNotIn         Sort order (exactly as it's sent to Solr) must not be in the given list
#
# Example: Boost more recent material if any of the search fields is of type
# "AllFields" or "Title" unless there's a search type specific boost:
#
# GlobalExtraParams:
#   - param: bf
#     value: "recip(ms(NOW/DAY,publishDateSort),1,1000,1000)"
#     conditions:
#       - SearchTypeIn:
#         - AllFields
#         - Title
#       - NoDismaxParams:
#         - bf
#         - bq
#       - SortIn:
#         - score desc,id asc
#
#
# Example: Boost material in English if any of the search fields is of type
# "AllFields" unless any of the search fields is of type "year":
#
# GlobalExtraParams:
#   - param: bq
#     value: "language:English^100"
#     conditions:
#       - SearchTypeNotIn: year
#       - SearchTypeIn: AllFields
#
#
#-----------------------------------------------------------------------------------
#
# Within the QueryFields area, fields are OR'd together, unless they're in an
# anonymous array with a numeric instead of alphanumeric key, in which case the
# first element is a two-value array that tells us what the type (AND or OR) and
# weight of the whole group should be.
#
# So, given:
#
# test:
#   QueryFields:
#     A:
#       - [onephrase, 500]
#       - [and, 200]
#     B:
#       - [and, 100]
#       - [or, 50]
#     # Start an anonymous array to group; first element indicates AND grouping
#     #     and a weight of 50
#     0:
#       0:
#         - AND
#         - 50
#       C:
#         - [onephrase, 200]
#       D:
#         - [onephrase, 300]
#       # Note the "not" attached to the field name as a minus, and the use of ~
#       #     to mean null ("no special weight")
#       -E:
#         - [or, ~]
#     D:
#       - [or, 100]
#
#  ...and the search string
#
#      test "one two"
#
#  ...we'd get
#
#   (A:"test one two"^500 OR
#    A:(test AND "one two")^ 200 OR
#    B:(test AND "one two")^100 OR
#    B:(test OR "one two")^50
#    (
#      C:("test one two")^200 AND
#      D:"test one two"^300 AND
#      -E:(test OR "one two")
#    )^50 OR
#    D:(test OR "one two")^100
#   )
#
#-----------------------------------------------------------------------------------
#
# Munge types are string manipulation rules, and consist of:
#
# onephrase: eliminate all quotes and do it as a single phrase.
#   testing "one two"
#    ...becomes ("testing one two")
#
# and: AND the terms together
#  testing "one two"
#   ...becomes (testing AND "one two")
#
# or: OR the terms together
#  testing "one two"
#   ...becomes (testing OR "one two")
#
# identity: Use the search as-is
#  testing "one two"
#   ...becomes (testing "one two")
#
# Additional Munge types can be defined in the CustomMunge section.  Each array
# entry under CustomMunge defines a new named munge type.  Each array entry under
# the name of the munge type specifies a string manipulation operation.  Operations
# will be applied in the order listed, and different operations take different
# numbers of parameters.
#
# Munge operations:
#
# [append, text] - Append text to the end of the user's search string
# [lowercase] - Convert string to lowercase
# [preg_replace, pattern, replacement] - Perform a regular expression replace
#     using the preg_replace() PHP function.  If you use backreferences in your
#     replacement phrase, be sure to escape dollar signs (i.e. \$1, not $1).
# [prepend, text] - Prepend text to the beginning of the user's search string
# [ucfirst] - Uppercase the first letter of each word in the string
# [uppercase] - Convert string to uppercase
#
# See the CallNumber search below for an example of custom munging in action.
#
#-----------------------------------------------------------------------------------
#
# Note that you may create a "@parent_yaml" entry at the very top of the file to
# inherit sections from another file. For example:
#
# "@parent_yaml": "/path/to/my/file.yaml"
#
# Only sections not found in this file will be loaded in from the parent file.
# In some complex scenarios, this can be a useful way of sharing settings
# between multiple configured VuFind instances. You can create a chain of parent
# files if necessary.
#
# If @parent_yaml cannot be accessed as an absolute path, it will also be tried
# relative to the path of the file defining it.
#
#-----------------------------------------------------------------------------------

# These searches use Dismax when possible:
Author:
  DismaxFields:
    - author^100
    - author2
    - author_additional
    - author_corporate
    - author_variant
    - author2_variant
  DismaxHandler: edismax

ISN:
  DismaxFields:
    - isbn
    - issn
  DismaxHandler: edismax

Subject:
  DismaxFields:
    - topic_unstemmed^150
    - topic^100
    - geographic^50
    - genre^50
    - era
  DismaxHandler: edismax
#  ExactSettings:
#    DismaxFields:
#      - topic_unstemmed^150


Coordinate:
  DismaxFields:
    - long_lat_display
  DismaxHandler: edismax

# This field definition is a compromise that supports both journal-level and
# article-level data.  The disadvantage is that hits in article titles will
# be mixed in.  If you are building a purely article-oriented index, you should
# customize this to remove all of the title_* fields and focus entirely on the
# container_title field.
JournalTitle:
  DismaxFields:
    - title_short^500
    - title_full_unstemmed^450
    - title_full^400
    - title^300
    - container_title^250
    - title_alt^200
    - title_new^100
    - title_old
    - series^100
    - series2
  DismaxHandler: edismax
  FilterQuery: "format:Journal OR format:Article"
#  ExactSettings:
#    DismaxFields:
#      - title_full_unstemmed^450
#    FilterQuery: "format:Journal OR format:Article"

Title:
  DismaxFields:
    - title_short^500
    - title_full_unstemmed^450
    - title_full^400
    - title^300
    - title_alt^200
    - title_new^100
    - title_old
    - series^100
    - series2
  DismaxHandler: edismax
#  ExactSettings:
#    DismaxFields:
#      - title_full_unstemmed^450

Series:
  DismaxFields:
    - series^100
    - series2
  DismaxHandler: edismax

AllFields:
  DismaxFields:
    - title_short^750
    - title_full_unstemmed^600
    - title_full^400
    - title^500
    - title_alt^200
    - title_new^100
    - series^50
    - series2^30
    - author^300
    - contents^10
    - topic_unstemmed^550
    - topic^500
    - geographic^300
    - genre^300
    - allfields_unstemmed^10
    - fulltext_unstemmed^10
    - allfields
    - fulltext
    - description
    - isbn
    - issn
    - long_lat_display
  DismaxHandler: edismax
#  ExactSettings:
#    DismaxFields:
#      - title_full_unstemmed^600
#      - topic_unstemmed^550
#      - allfields_unstemmed^10
#      - fulltext_unstemmed^10
#      - isbn
#      - issn

# These are advanced searches that never use Dismax:
id:
  QueryFields:
    id:
      - [onephrase, ~]

ParentID:
  QueryFields:
    hierarchy_parent_id:
      - [onephrase, ~]

# Fields for exact matches originating from alphabetic browse
ids:
  QueryFields:
    id:
      - [or, ~]

TopicBrowse:
  QueryFields:
    topic_browse:
      - [onephrase, ~]

AuthorBrowse:
  QueryFields:
    author_browse:
      - [onephrase, ~]

TitleBrowse:
  QueryFields:
    title_full:
      - [onephrase, ~]

DeweyBrowse:
  QueryFields:
    dewey-raw:
      - [onephrase, ~]

LccBrowse:
  QueryFields:
    callnumber-raw:
      - [onephrase, ~]

CallNumber:
  # We use two similar munges here -- one for exact matches, which will get
  # a very high boost factor, and one for left-anchored wildcard searches,
  # which will return a larger number of hits at a lower boost.
  CustomMunge:
    callnumber_exact:
      # Strip whitespace and quotes:
      - [preg_replace, '/[ "]/', '']
      # Escape colons (unescape first to avoid double-escapes):
      - [preg_replace, '/(\\:)/', ':']
      - [preg_replace, '/:/', '\:']
      # Strip pre-existing trailing asterisks:
      - [preg_replace, '/\*+$/', '']
    callnumber_fuzzy:
      # Strip whitespace and quotes:
      - [preg_replace, '/[ "]/', '']
      # Escape colons (unescape first to avoid double-escapes):
      - [preg_replace, '/(\\:)/', ':']
      - [preg_replace, '/:/', '\:']
      # Strip pre-existing trailing asterisks, then add a new one:
      - [preg_replace, '/\*+$/', '']
      - [append, "*"]
  QueryFields:
    callnumber-search:
      - [callnumber_exact, 1000]
      - [callnumber_fuzzy, ~]
    dewey-search:
      - [callnumber_exact, 1000]
      - [callnumber_fuzzy, ~]

publisher:
  DismaxFields:
    - publisher^100
  QueryFields:
    publisher:
      - [and, 100]
      - [or, ~]

year:
  DismaxFields:
    - publishDate^100
  QueryFields:
    publishDate:
      - [and, 100]
      - [or, ~]

language:
  QueryFields:
    language:
      - [and, ~]

toc:
  DismaxFields:
    - contents^100
  QueryFields:
    contents:
      - [and, 100]
      - [or, ~]

topic:
  QueryFields:
    topic:
      - [and, 50]
    topic_facet:
      - [and, ~]

geographic:
  QueryFields:
    geographic:
      - [and, 50]
    geographic_facet:
      - [and, ~]

genre:
  QueryFields:
    genre:
      - [and, 50]
    genre_facet:
      - [and, ~]

era:
  QueryFields:
    era:
      - [and, ~]

oclc_num:
  CustomMunge:
    oclc_num:
      - [preg_replace, "/[^0-9]/", ""]
      # trim leading zeroes:
      - [preg_replace, "/^0*/", ""]
  QueryFields:
    oclc_num:
      - [oclc_num, ~]

WorkKeys:
  QueryFields:
    work_keys_str_mv:
      - [and, 100]
      - [or, ~]
