Bug 12478: Move mapping attributes to the join table
[koha.git] / installer / data / mysql / atomicupdate / elastic_search.perl
1 #!/usr/bin/perl
2
3 use Modern::Perl;
4
5 use C4::Context;
6 use YAML::Syck;
7
8 use Koha::SearchMarcMaps;
9 use Koha::SearchFields;
10
11 my $dbh = C4::Context->dbh;
12
13 $dbh->do(q|DROP TABLE IF EXISTS search_marc_to_field|);
14 $dbh->do(q|DROP TABLE IF EXISTS search_marc_map|);
15 $dbh->do(q|DROP TABLE IF EXISTS search_field|);
16
17 # This specifies the fields that will be stored in the search engine.
18 $dbh->do(q|
19     CREATE TABLE `search_field` (
20       `id` int(11) NOT NULL AUTO_INCREMENT,
21       `name` varchar(255) NOT NULL COMMENT 'the name of the field as it will be stored in the search engine',
22       `label` varchar(255) NOT NULL COMMENT 'the human readable name of the field, for display',
23       `type` ENUM('string', 'date', 'number', 'boolean', 'sum') NOT NULL COMMENT 'what type of data this holds, relevant when storing it in the search engine',
24       PRIMARY KEY (`id`),
25       UNIQUE KEY (`name`)
26     ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
27 |);
28
29 # This contains a MARC field specifier for a given index, marc type, and marc
30 # field.
31 $dbh->do(q|
32     CREATE TABLE `search_marc_map` (
33         id int(11) NOT NULL AUTO_INCREMENT,
34         index_name ENUM('biblios','authorities') NOT NULL COMMENT 'what storage index this map is for',
35         marc_type ENUM('marc21', 'unimarc', 'normarc') NOT NULL COMMENT 'what MARC type this map is for',
36         marc_field VARCHAR(255) NOT NULL COMMENT 'the MARC specifier for this field',
37         PRIMARY KEY(`id`),
38         unique key( index_name, marc_field, marc_type),
39         INDEX (`index_name`)
40     ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
41 |);
42
43 # This joins the two search tables together. We can have any combination:
44 # one marc field could have many search fields (maybe you want one value
45 # to go to 'author' and 'corporate-author) and many marc fields could go
46 # to one search field (e.g. all the various author fields going into
47 # 'author'.)
48 #
49 # a note about the sort field:
50 # * if all the entries for a mapping are 'null', nothing special is done with that mapping.
51 # * if any of the entries are not null, then a __sort field is created in ES for this mapping. In this case:
52 #   * any mapping with sort == false WILL NOT get copied into a __sort field
53 #   * any mapping with sort == true or is null WILL get copied into a __sort field
54 #   * any sorts on the field name will be applied to $fieldname.'__sort' instead.
55 # this means that we can have search for author that includes 1xx, 245$c, and 7xx, but the sort only applies to 1xx.
56 $dbh->do(q|
57     CREATE TABLE `search_marc_to_field` (
58         search_marc_map_id int(11) NOT NULL,
59         search_field_id int(11) NOT NULL,
60         facet boolean DEFAULT FALSE COMMENT 'true if a facet field should be generated for this',
61         suggestible boolean DEFAULT FALSE COMMENT 'true if this field can be used to generate suggestions for browse',
62         sort boolean DEFAULT NULL COMMENT 'true/false creates special sort handling, null doesn''t',
63         PRIMARY KEY(search_marc_map_id, search_field_id),
64         FOREIGN KEY(search_marc_map_id) REFERENCES search_marc_map(id) ON DELETE CASCADE ON UPDATE CASCADE,
65         FOREIGN KEY(search_field_id) REFERENCES search_field(id) ON DELETE CASCADE ON UPDATE CASCADE
66     ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
67 |);
68
69 my $mappings_yaml = C4::Context->config('intranetdir') . '/admin/searchengine/elasticsearch/mappings.yaml';
70 my $indexes = LoadFile( $mappings_yaml );
71
72 while ( my ( $index_name, $fields ) = each %$indexes ) {
73     while ( my ( $field_name, $data ) = each %$fields ) {
74         my $field_type = $data->{type};
75         my $field_label = $data->{label};
76         my $mappings = $data->{mappings};
77         my $search_field = Koha::SearchFields->find_or_create({ name => $field_name, label => $field_label, type => $field_type }, { key => 'name' });
78         for my $mapping ( @$mappings ) {
79             my $marc_field = Koha::SearchMarcMaps->find_or_create({ index_name => $index_name, marc_type => $mapping->{marc_type}, marc_field => $mapping->{marc_field} });
80             $search_field->add_to_search_marc_maps($marc_field, { facet => $mapping->{facet}, suggestible => $mapping->{suggestible}, sort => $mapping->{sort} } );
81         }
82     }
83 }