mabmapper 1.0.0.pre15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (221) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/.travis.yml +4 -0
  4. data/Gemfile +7 -0
  5. data/LICENSE +22 -0
  6. data/README.md +49 -0
  7. data/Rakefile +29 -0
  8. data/bin/mabmapper +3 -0
  9. data/lib/mabmapper/aleph_mab_xml_engine.rb +1050 -0
  10. data/lib/mabmapper/cli.rb +216 -0
  11. data/lib/mabmapper/elasticsearch_writer.rb +52 -0
  12. data/lib/mabmapper/engine.rb +112 -0
  13. data/lib/mabmapper/mab_xml/document.rb +53 -0
  14. data/lib/mabmapper/mab_xml/field.rb +43 -0
  15. data/lib/mabmapper/mab_xml/query.rb +25 -0
  16. data/lib/mabmapper/mab_xml/query_helper.rb +101 -0
  17. data/lib/mabmapper/mab_xml/result_set.rb +34 -0
  18. data/lib/mabmapper/mab_xml/subfield.rb +12 -0
  19. data/lib/mabmapper/mab_xml.rb +6 -0
  20. data/lib/mabmapper/tar_writer.rb +29 -0
  21. data/lib/mabmapper/version.rb +3 -0
  22. data/lib/mabmapper.rb +11 -0
  23. data/mabmapper.gemspec +33 -0
  24. data/test/mab_files/test_creation_date/test1.xml +17 -0
  25. data/test/mab_files/test_creation_date/test2.xml +17 -0
  26. data/test/mab_files/test_creationdate/425_a_1.xml +17 -0
  27. data/test/mab_files/test_creationdate/425_a_2.xml +19 -0
  28. data/test/mab_files/test_creationdate/425_bc_1.xml +19 -0
  29. data/test/mab_files/test_creationdate/425_bc_2.xml +22 -0
  30. data/test/mab_files/test_creationdate/425_bc_3.xml +22 -0
  31. data/test/mab_files/test_creationdate/425_bc_4.xml +19 -0
  32. data/test/mab_files/test_creationdate/425_p_1.xml +19 -0
  33. data/test/mab_files/test_creationdate/425_p_2.xml +17 -0
  34. data/test/mab_files/test_creationdate/595_1.xml +20 -0
  35. data/test/mab_files/test_creator_contributor_facet/PAD01.001006945.PRIMO.xml +574 -0
  36. data/test/mab_files/test_description/405.xml +22 -0
  37. data/test/mab_files/test_description/501-519.xml +30 -0
  38. data/test/mab_files/test_description/522.xml +22 -0
  39. data/test/mab_files/test_description/523.xml +22 -0
  40. data/test/mab_files/test_description/536-537.xml +30 -0
  41. data/test/mab_files/test_doc/PAD01.001510737.PRIMO.xml +317 -0
  42. data/test/mab_files/test_edition/PAD01.000844686.PRIMO.xml +584 -0
  43. data/test/mab_files/test_edition/PAD01.000969531.PRIMO.xml +129 -0
  44. data/test/mab_files/test_edition/PAD01.000969710.PRIMO.xml +144 -0
  45. data/test/mab_files/test_edition/PAD01.000978033.PRIMO.xml +163 -0
  46. data/test/mab_files/test_edition/PAD01.000990520.PRIMO.xml +163 -0
  47. data/test/mab_files/test_erscheinungsform/PAD01.000870753.PRIMO.xml +256 -0
  48. data/test/mab_files/test_erscheinungsform/PAD01.000870755.PRIMO.xml +467 -0
  49. data/test/mab_files/test_ht_number/PAD01.001015067.PRIMO.xml +137 -0
  50. data/test/mab_files/test_inhaltstyp/PAD01.000870753.PRIMO.xml +256 -0
  51. data/test/mab_files/test_inhaltstyp/PAD01.000870755.PRIMO.xml +467 -0
  52. data/test/mab_files/test_is_secondary_form/PAD01.000806191.PRIMO.xml +216 -0
  53. data/test/mab_files/test_is_secondary_form/PAD01.000844686.PRIMO.xml +584 -0
  54. data/test/mab_files/test_is_secondary_form/PAD01.001015067.PRIMO.xml +137 -0
  55. data/test/mab_files/test_is_secondary_form/PAD01.001452439.PRIMO.xml +377 -0
  56. data/test/mab_files/test_is_suborder/PAD01.000806191.PRIMO.xml +216 -0
  57. data/test/mab_files/test_is_suborder/PAD01.000844686.PRIMO.xml +584 -0
  58. data/test/mab_files/test_is_suborder/PAD01.001452439.PRIMO.xml +377 -0
  59. data/test/mab_files/test_issn/PAD01.000637121.PRIMO.xml +805 -0
  60. data/test/mab_files/test_materialtyp/PAD01.000870753.PRIMO.xml +256 -0
  61. data/test/mab_files/test_materialtyp/PAD01.000870755.PRIMO.xml +467 -0
  62. data/test/mab_files/test_notation_sort/PAD01.000970649.PRIMO.xml +306 -0
  63. data/test/mab_files/test_notation_sort/PAD01.001006944.PRIMO.xml +279 -0
  64. data/test/mab_files/test_publisher/PAD01.000312406.PRIMO.xml +1043 -0
  65. data/test/mab_files/test_redactional_remark/PAD01.001510737.PRIMO.xml +317 -0
  66. data/test/mab_files/test_relation/PAD01.000438377.PRIMO.xml +232 -0
  67. data/test/mab_files/test_relation/PAD01.000637121.PRIMO.xml +810 -0
  68. data/test/mab_files/test_relation/PAD01.000806191.PRIMO.xml +216 -0
  69. data/test/mab_files/test_relation/PAD01.000844686.PRIMO.xml +584 -0
  70. data/test/mab_files/test_relation/PAD01.001452439.PRIMO.xml +377 -0
  71. data/test/mab_files/test_secondary_form_creationdate/PAD01.000806191.PRIMO.xml +216 -0
  72. data/test/mab_files/test_secondary_form_creationdate/PAD01.000844686.PRIMO.xml +584 -0
  73. data/test/mab_files/test_secondary_form_creationdate/PAD01.001452439.PRIMO.xml +377 -0
  74. data/test/mab_files/test_secondary_form_isbn/PAD01.000806191.PRIMO.xml +216 -0
  75. data/test/mab_files/test_secondary_form_isbn/PAD01.000844686.PRIMO.xml +584 -0
  76. data/test/mab_files/test_secondary_form_isbn/PAD01.001452439.PRIMO.xml +377 -0
  77. data/test/mab_files/test_secondary_form_physical_description/PAD01.000806191.PRIMO.xml +216 -0
  78. data/test/mab_files/test_secondary_form_physical_description/PAD01.001452439.PRIMO.xml +377 -0
  79. data/test/mab_files/test_secondary_form_preliminary_phrase/PAD01.000806191.PRIMO.xml +216 -0
  80. data/test/mab_files/test_secondary_form_preliminary_phrase/PAD01.001452439.PRIMO.xml +377 -0
  81. data/test/mab_files/test_secondary_form_publisher/PAD01.000806191.PRIMO.xml +216 -0
  82. data/test/mab_files/test_secondary_form_publisher/PAD01.001452439.PRIMO.xml +377 -0
  83. data/test/mab_files/test_secondary_form_superorder/PAD01.000806191.PRIMO.xml +216 -0
  84. data/test/mab_files/test_secondary_form_superorder/PAD01.000977734.PRIMO.xml +225 -0
  85. data/test/mab_files/test_secondary_form_superorder/PAD01.001452439.PRIMO.xml +377 -0
  86. data/test/mab_files/test_short_title_display/PAD01.000057960.PRIMO.xml +1069 -0
  87. data/test/mab_files/test_short_title_display/PAD01.000058000.PRIMO.xml +995 -0
  88. data/test/mab_files/test_short_title_display/PAD01.000215104.PRIMO.xml +191 -0
  89. data/test/mab_files/test_short_title_display/PAD01.000310864.PRIMO.xml +999 -0
  90. data/test/mab_files/test_short_title_display/PAD01.000392641.PRIMO.xml +4334 -0
  91. data/test/mab_files/test_short_title_display/PAD01.000392645.PRIMO.xml +4094 -0
  92. data/test/mab_files/test_short_title_display/PAD01.000438377.PRIMO.xml +232 -0
  93. data/test/mab_files/test_short_title_display/PAD01.000479391.PRIMO.xml +142 -0
  94. data/test/mab_files/test_short_title_display/PAD01.000637121.PRIMO.xml +805 -0
  95. data/test/mab_files/test_short_title_display/PAD01.000676616.PRIMO.xml +128 -0
  96. data/test/mab_files/test_short_title_display/PAD01.000782994.PRIMO.xml +169 -0
  97. data/test/mab_files/test_short_title_display/PAD01.001006945.PRIMO.xml +574 -0
  98. data/test/mab_files/test_short_title_display/PAD01.001015067.PRIMO.xml +137 -0
  99. data/test/mab_files/test_short_title_display/PAD01.001015070.PRIMO.xml +212 -0
  100. data/test/mab_files/test_short_title_display/PAD01.001108212.PRIMO.xml +259 -0
  101. data/test/mab_files/test_short_title_display/PAD01.001249043.PRIMO.xml +172 -0
  102. data/test/mab_files/test_short_title_display/PAD01.001499877.PRIMO.xml +227 -0
  103. data/test/mab_files/test_short_title_display/PAD01.001499879.PRIMO.xml +255 -0
  104. data/test/mab_files/test_short_title_display/PAD01.001499880.PRIMO.xml +279 -0
  105. data/test/mab_files/test_short_title_display/PAD01.001510878.PRIMO.xml +184 -0
  106. data/test/mab_files/test_short_title_display/PAD01.001562173.PRIMO.xml +116 -0
  107. data/test/mab_files/test_short_title_display/PAD01.001568334.PRIMO.xml +1840 -0
  108. data/test/mab_files/test_short_title_display/PAD01.001572048.PRIMO.xml +68 -0
  109. data/test/mab_files/test_short_title_display/PAD01.001572049.PRIMO.xml +133 -0
  110. data/test/mab_files/test_signature/PAD01.000161445.PRIMO.xml +149 -0
  111. data/test/mab_files/test_signature/PAD01.000321365.PRIMO.xml +343 -0
  112. data/test/mab_files/test_signature/PAD01.000636652.PRIMO.xml +217 -0
  113. data/test/mab_files/test_signature/PAD01.000857994.PRIMO.xml +187 -0
  114. data/test/mab_files/test_signature/PAD01.000859176.PRIMO.xml +559 -0
  115. data/test/mab_files/test_signature/PAD01.000969442.PRIMO.xml +210 -0
  116. data/test/mab_files/test_signature/PAD01.001006945.PRIMO.xml +574 -0
  117. data/test/mab_files/test_signature_search/PAD01.000161445.PRIMO.xml +149 -0
  118. data/test/mab_files/test_signature_search/PAD01.000321365.PRIMO.xml +343 -0
  119. data/test/mab_files/test_signature_search/PAD01.000636652.PRIMO.xml +217 -0
  120. data/test/mab_files/test_signature_search/PAD01.000857994.PRIMO.xml +187 -0
  121. data/test/mab_files/test_signature_search/PAD01.000859176.PRIMO.xml +559 -0
  122. data/test/mab_files/test_signature_search/PAD01.000969442.PRIMO.xml +210 -0
  123. data/test/mab_files/test_signature_search/PAD01.001006945.PRIMO.xml +574 -0
  124. data/test/mab_files/test_status/PAD01.000321365.PRIMO.xml +343 -0
  125. data/test/mab_files/test_status/PAD01.000392641.PRIMO.xml +4337 -0
  126. data/test/mab_files/test_status/detmold_1.xml +17 -0
  127. data/test/mab_files/test_status/detmold_2.xml +17 -0
  128. data/test/mab_files/test_status/detmold_3.xml +12 -0
  129. data/test/mab_files/test_subject/PAD01.000972511.PRIMO.xml +406 -0
  130. data/test/mab_files/test_suborders/PAD01.000057960.PRIMO.xml +1069 -0
  131. data/test/mab_files/test_suborders/PAD01.000058000.PRIMO.xml +995 -0
  132. data/test/mab_files/test_suborders/PAD01.000215104.PRIMO.xml +191 -0
  133. data/test/mab_files/test_suborders/PAD01.000310864.PRIMO.xml +999 -0
  134. data/test/mab_files/test_suborders/PAD01.000392641.PRIMO.xml +4334 -0
  135. data/test/mab_files/test_suborders/PAD01.000392645.PRIMO.xml +4094 -0
  136. data/test/mab_files/test_suborders/PAD01.000438377.PRIMO.xml +232 -0
  137. data/test/mab_files/test_suborders/PAD01.000479391.PRIMO.xml +142 -0
  138. data/test/mab_files/test_suborders/PAD01.000637121.PRIMO.xml +805 -0
  139. data/test/mab_files/test_suborders/PAD01.000676616.PRIMO.xml +128 -0
  140. data/test/mab_files/test_suborders/PAD01.001006945.PRIMO.xml +574 -0
  141. data/test/mab_files/test_suborders/PAD01.001015067.PRIMO.xml +137 -0
  142. data/test/mab_files/test_suborders/PAD01.001015068.PRIMO.xml +216 -0
  143. data/test/mab_files/test_suborders/PAD01.001015070.PRIMO.xml +212 -0
  144. data/test/mab_files/test_suborders/PAD01.001108212.PRIMO.xml +259 -0
  145. data/test/mab_files/test_suborders/PAD01.001499877.PRIMO.xml +227 -0
  146. data/test/mab_files/test_suborders/PAD01.001499879.PRIMO.xml +255 -0
  147. data/test/mab_files/test_suborders/PAD01.001499880.PRIMO.xml +279 -0
  148. data/test/mab_files/test_suborders/PAD01.001562173.PRIMO.xml +116 -0
  149. data/test/mab_files/test_suborders/PAD01.001572048.PRIMO.xml +68 -0
  150. data/test/mab_files/test_suborders/PAD01.001572049.PRIMO.xml +133 -0
  151. data/test/mab_files/test_superorder/PAD01.000806191.PRIMO.xml +216 -0
  152. data/test/mab_files/test_superorder/PAD01.000844686.PRIMO.xml +584 -0
  153. data/test/mab_files/test_superorder/PAD01.001015067.PRIMO.xml +137 -0
  154. data/test/mab_files/test_superorder/PAD01.001452439.PRIMO.xml +377 -0
  155. data/test/mab_files/test_superorder_display/PAD01.000000872.PRIMO.xml +227 -0
  156. data/test/mab_files/test_superorder_display/PAD01.000160412.PRIMO.xml +518 -0
  157. data/test/mab_files/test_superorder_display/PAD01.000162669.PRIMO.xml +198 -0
  158. data/test/mab_files/test_superorder_display/PAD01.000178500.PRIMO.xml +158 -0
  159. data/test/mab_files/test_superorder_display/PAD01.000297043.PRIMO.xml +154 -0
  160. data/test/mab_files/test_superorder_display/PAD01.000562878.PRIMO.xml +1214 -0
  161. data/test/mab_files/test_superorder_display/PAD01.000958473.PRIMO.xml +379 -0
  162. data/test/mab_files/test_superorder_display/PAD01.001006945.PRIMO.xml +574 -0
  163. data/test/mab_files/test_superorders/PAD01.000057960.PRIMO.xml +1069 -0
  164. data/test/mab_files/test_superorders/PAD01.000215104.PRIMO.xml +191 -0
  165. data/test/mab_files/test_superorders/PAD01.000310864.PRIMO.xml +999 -0
  166. data/test/mab_files/test_superorders/PAD01.000392641.PRIMO.xml +4334 -0
  167. data/test/mab_files/test_superorders/PAD01.000438377.PRIMO.xml +232 -0
  168. data/test/mab_files/test_superorders/PAD01.000479391.PRIMO.xml +142 -0
  169. data/test/mab_files/test_superorders/PAD01.000637121.PRIMO.xml +805 -0
  170. data/test/mab_files/test_superorders/PAD01.001015067.PRIMO.xml +137 -0
  171. data/test/mab_files/test_superorders/PAD01.001499877.PRIMO.xml +227 -0
  172. data/test/mab_files/test_superorders/PAD01.001572048.PRIMO.xml +68 -0
  173. data/test/mab_files/test_title_display/PAD01.000954111.PRIMO.xml +162 -0
  174. data/test/mab_files/test_title_display/PAD01.000992332.PRIMO.xml +189 -0
  175. data/test/mab_files/test_title_display/PAD01.001015068.PRIMO.xml +216 -0
  176. data/test/mab_files/test_title_display/PAD01.001499879.PRIMO.xml +255 -0
  177. data/test/mab_files/test_title_search/test_1.xml +20 -0
  178. data/test/mab_files/test_title_sort/PAD01.000954111.PRIMO.xml +162 -0
  179. data/test/mab_files/test_title_sort/PAD01.000992332.PRIMO.xml +189 -0
  180. data/test/mab_files/test_volume_count_sort/PAD01.001015068.PRIMO.xml +216 -0
  181. data/test/mab_files/test_volume_count_sort/PAD01.001499879.PRIMO.xml +255 -0
  182. data/test/mabmapper/test_creation_date.rb +5 -0
  183. data/test/mabmapper/test_creationdate.rb +23 -0
  184. data/test/mabmapper/test_creator_contributor_facet.rb +4 -0
  185. data/test/mabmapper/test_description.rb +9 -0
  186. data/test/mabmapper/test_doc.rb +6 -0
  187. data/test/mabmapper/test_edition.rb +8 -0
  188. data/test/mabmapper/test_erscheinungsform.rb +5 -0
  189. data/test/mabmapper/test_ht_number.rb +4 -0
  190. data/test/mabmapper/test_inhaltstyp.rb +5 -0
  191. data/test/mabmapper/test_is_secondary_form.rb +7 -0
  192. data/test/mabmapper/test_is_suborder.rb +7 -0
  193. data/test/mabmapper/test_issn.rb +4 -0
  194. data/test/mabmapper/test_materialtyp.rb +5 -0
  195. data/test/mabmapper/test_notation_sort.rb +5 -0
  196. data/test/mabmapper/test_publisher.rb +5 -0
  197. data/test/mabmapper/test_redactional_remark.rb +4 -0
  198. data/test/mabmapper/test_relation.rb +16 -0
  199. data/test/mabmapper/test_secondary_form_creationdate.rb +6 -0
  200. data/test/mabmapper/test_secondary_form_isbn.rb +6 -0
  201. data/test/mabmapper/test_secondary_form_physical_description.rb +5 -0
  202. data/test/mabmapper/test_secondary_form_preliminary_phrase.rb +5 -0
  203. data/test/mabmapper/test_secondary_form_publisher.rb +5 -0
  204. data/test/mabmapper/test_secondary_form_superorder.rb +9 -0
  205. data/test/mabmapper/test_short_title_display.rb +27 -0
  206. data/test/mabmapper/test_signature.rb +12 -0
  207. data/test/mabmapper/test_signature_search.rb +12 -0
  208. data/test/mabmapper/test_status.rb +13 -0
  209. data/test/mabmapper/test_subject.rb +5 -0
  210. data/test/mabmapper/test_suborders.rb +192 -0
  211. data/test/mabmapper/test_superorder.rb +7 -0
  212. data/test/mabmapper/test_superorder_display.rb +22 -0
  213. data/test/mabmapper/test_superorders.rb +38 -0
  214. data/test/mabmapper/test_title_display.rb +12 -0
  215. data/test/mabmapper/test_title_search.rb +4 -0
  216. data/test/mabmapper/test_title_sort.rb +6 -0
  217. data/test/mabmapper/test_volume_count_sort.rb +5 -0
  218. data/test/test_helper.rb +53 -0
  219. data/test/test_mabmapper.rb +19 -0
  220. data/utils/mab_by_docid.sh +19 -0
  221. metadata +574 -0
@@ -0,0 +1,1050 @@
1
+ # coding: utf-8
2
+ module Mabmapper
3
+ class AlephMabXmlEngine < Engine
4
+
5
+ document_class MabXml::Document
6
+
7
+ #
8
+ # Id
9
+ #
10
+ field :id do
11
+ doc.controlfield('SYS').join
12
+ end
13
+
14
+ #
15
+ # Status - Neu (A) oder gelöscht (D)
16
+ #
17
+ field :status do
18
+ value = 'A'
19
+
20
+ # gelöscht -> LDR Position 6 == 'd'
21
+ value = 'D' if doc.controlfield('LDR').at(5) == 'd'
22
+ # ausgesondert über Feld 078
23
+ value = 'D' if doc.field('078', ind1: 'r').subfield('a').get.value.try(:downcase) == 'aus'
24
+ # Standort Detmold unterdrücken
25
+ detmold_locations = doc.field('LOC').subfield('n').get.values.flatten
26
+ value = 'D' if detmold_locations.present? && detmold_locations.all?{|v| v == '50'}
27
+
28
+ value
29
+ end
30
+
31
+ #
32
+ # HT Nummer
33
+ #
34
+ field :ht_number do
35
+ doc.field('001', ind2: '1').subfield('a').get.value
36
+ end
37
+
38
+ #
39
+ # Creation date
40
+ #
41
+ field :creation_date do
42
+ doc.field('LOC', ind2: ' ').subfield('k').get.values.flatten.map(&:presence).compact.uniq
43
+ end
44
+
45
+ #
46
+ # Materialtyp
47
+ #
48
+ field :materialtyp do
49
+ f050 = doc.controlfield('050')
50
+ type = case
51
+ when (%w(a ).include?(f050.at( 0)) ) then 'print'
52
+ when (%w(a b c).include?(f050.at( 3)) ) then 'microform'
53
+ when (%w(a ).include?(f050.at( 5)) ) then 'audio'
54
+ when (%w(b c z).include?(f050.at( 5)) ) then 'video'
55
+ when (%w(d ).include?(f050.at( 5)) ) then 'image'
56
+ when (%w(d ).include?(f050.at( 8)) ) then 'data_storage'
57
+ when (%w(g ).include?(f050.at( 8)) ) then 'online_resource'
58
+ when (%w(a ).include?(f050.at( 9)) ) then 'game'
59
+ when (%w(a ).include?(f050.at(10)) ) then 'map'
60
+ else 'other'
61
+ end
62
+ type
63
+ end
64
+
65
+ #
66
+ # Inhaltstyp
67
+ #
68
+ field :inhaltstyp do
69
+ f051 = doc.controlfield('051')
70
+ f052 = doc.controlfield('052')
71
+ f051s = f051.join.slice(1..3) || ""
72
+ f052s = f052.join.slice(1..6) || ""
73
+
74
+ type = case
75
+ # Monos
76
+ when (f051s.include?('b')) then 'bibliography'
77
+ when (f051s.include?('c')) then 'catalog'
78
+ when (f051s.include?('d')) then 'dictionary'
79
+ when (f051s.include?('e')) then 'encyclopedia'
80
+ when (f051s.include?('f')) then 'festschrift'
81
+ when (f051s.include?('h')) then 'biography'
82
+ when (f051s.include?('k')) then 'congress'
83
+ when (f051s.include?('m')) then 'music'
84
+ when (f051s.include?('n')) then 'standard'
85
+ when (f051s.include?('u')) then 'university_text'
86
+ when (f051s.include?('x')) then 'textbook'
87
+ when (f051s.include?('y')) then 'dissertation'
88
+ # Fortlaufende Sammelwerke (Zeitschriften u.ä.)
89
+ when (f052s.include?('bi')) then 'bibliography'
90
+ when (f052s.include?('ww')) then 'dissertation'
91
+ when (f052s.include?('fs')) then 'festschrift'
92
+ when (f052s.include?('ko')) then 'congress'
93
+ when (f052s.include?('wb')) then 'dictionary'
94
+ when (f052s.include?('ez')) then 'encyclopedia'
95
+ when (f052s.include?('bg')) then 'biography'
96
+ when (f052s.include?('mu')) then 'music'
97
+ when (f052s.include?('no')) then 'standard'
98
+ when (f052s.include?('sc')) then 'textbook'
99
+ # ... der Rest
100
+ else 'other'
101
+ end
102
+
103
+ type
104
+ end
105
+
106
+ #
107
+ # Bandzähler von Reihen / Stücktiteln
108
+ #
109
+ field :volume_count do
110
+ # Bandzählung von Reihen
111
+ volumes = []
112
+ (456..496).step(10) do |f|
113
+ value = doc.field("#{f}", ind2: '1').subfield('a').get.value
114
+ volumes << value if value.present?
115
+ end
116
+ volumes.first
117
+ end
118
+
119
+ #
120
+ # Title
121
+ #
122
+ field :title do
123
+ f331_2 = doc.field('331', ind2: '2').subfield('a').get.value
124
+ f333_2 = doc.field('333', ind2: '2').subfield('a').get.value
125
+ f335_2 = doc.field('335', ind2: '2').subfield('a').get.value
126
+ f360_2 = doc.field('360', ind2: '2').subfield('a').get.value
127
+
128
+ f089_1 = doc.field('089', ind2: '1').subfield('a').get.value
129
+ f331_1 = doc.field('331', ind2: '1').subfield('a').get.value
130
+ f333_1 = doc.field('333', ind2: '1').subfield('a').get.value
131
+ f335_1 = doc.field('335', ind2: '1').subfield('a').get.value
132
+ f360_1 = doc.field('360', ind2: '1').subfield('a').get.value
133
+ f304_1 = doc.field('304', ind2: '1').subfield('a').get.value
134
+ f310_1 = doc.field('310', ind2: '1').subfield('a').get.value
135
+ f340_1 = doc.field('340', ind2: '1').subfield('a').get.value
136
+ f341_1 = doc.field('341', ind2: '1').subfield('a').get.value
137
+
138
+ title = merge(title, f331_2, delimiter: '. ')
139
+ title = merge(title, f333_2, delimiter: ' / ')
140
+ title = merge(title, f335_2, delimiter: ' : ')
141
+ title = merge(title, f360_2, delimiter: '. ')
142
+
143
+ title = merge(title, f089_1, delimiter: ". #{(f089_1.present? && f089_1.length <= 3) ? 'Bd. ' : ''}") # only add 'Bd.' if Bandzählung is something trivial like 123, A or B-C
144
+ title = merge(title, f331_1, delimiter: '. ')
145
+ title = merge(title, f333_1, delimiter: ' / ')
146
+ title = merge(title, f335_1, delimiter: ' : ')
147
+ title = merge(title, f360_1, delimiter: '. ')
148
+ title = merge(title, f304_1, delimiter: '. ')
149
+ title = merge(title, f310_1, delimiter: ' ', wrap: '[@]')
150
+ title = merge(title, f340_1.presence || f341_1, delimiter: ' = ')
151
+
152
+ title.presence || '–'
153
+ end
154
+
155
+ field :title_display do
156
+ ref(:title).gsub(/<<|>>/, '')
157
+ end
158
+
159
+ field :title_sort do
160
+ ref(:title).gsub(/<<.*>>/, '').gsub(/\s\s/, ' ').strip
161
+ end
162
+
163
+ field :short_title_display do
164
+ # 331 => Titel, 335 Titelzusatz (ind2 == 1 -> betrachteter Titel, ind2 == 2 -> Überordnung)
165
+ f089_1 = doc.field('089', ind2: '1').subfield('a').get.value
166
+ f331_1 = doc.field('331', ind2: '1').subfield('a').get.value
167
+ f331_2 = doc.field('331', ind2: '2').subfield('a').get.value
168
+ f335_1 = doc.field('335', ind2: '1').subfield('a').get.value
169
+
170
+ short_title = if (f331_1 && f335_1)
171
+ "#{f331_1} : #{f335_1}"
172
+ elsif f331_1
173
+ f331_1
174
+ elsif f089_1 && f089_1.length > 3 && f089_1[/\A(\d|\s)+\Z/].nil? && !['buch', 'hauptbd.'].include?(f089_1.gsub(/\[|\]/, '').downcase)
175
+ f089_1.gsub(/.*(bd|Bd).*\,/, '') # Try to remove volume count from
176
+ elsif f331_2
177
+ f331_2
178
+ else
179
+ ''
180
+ end
181
+
182
+ short_title.gsub!(/<<|>>/, '')
183
+ short_title.strip!
184
+ short_title[0] = short_title[0].upcase if short_title.present?
185
+ short_title.presence
186
+ end
187
+
188
+ field :title_search do
189
+ search_titles = []
190
+ search_titles << ref(:title_display)
191
+
192
+ (342..355).each do |f|
193
+ search_titles << doc.field("#{f}", ind2: '1').subfield('a').get.values
194
+ end
195
+
196
+ search_titles << doc.field('370', ind2: '1').subfield('a').get.values
197
+
198
+ search_titles << doc.field('376', ind2: '1').subfield('a').get.values
199
+ (451..491).step(10).each do |f|
200
+ search_titles << doc.field("#{f}", ind2: '1').subfield('a').get.values
201
+ end
202
+ search_titles << doc.field('502', ind2: '1').subfield('a').get.values
203
+ search_titles << doc.field('504', ind2: '1').subfield('a').get.values
204
+ search_titles << doc.field('505', ind2: '1').subfield('a').get.values
205
+ (526..534).each do |f|
206
+ search_titles << doc.field("#{f}", ind2: '1').subfield('a').get.values
207
+ end
208
+ search_titles << doc.field('621', ind2: '1').subfield('a').get.values
209
+ search_titles << doc.field('627', ind2: '1').subfield('a').get.values
210
+ search_titles << doc.field('633', ind2: '1').subfield('a').get.values
211
+
212
+ search_titles.flatten.map(&:presence).compact.uniq
213
+ end
214
+
215
+
216
+ #
217
+ # Creator
218
+ #
219
+ field :creator_contributor_display do
220
+ creators = []
221
+
222
+ # Personen
223
+ (100..196).step(4) do |f|
224
+ creators << doc.field("#{f}", ind2: ['1', '2']).subfield(['a','p','c','n','b']).get.value
225
+ end
226
+
227
+ # Körperschaften
228
+ (200..296).step(4) do |f|
229
+ creators << doc.field("#{f}", ind2: ['1', '2']).subfield(['a','k','b','e','c','n','g','h']).get.value
230
+ end
231
+
232
+ # Sonderfall: Verfasserangaben aus 359 -> [u.a.]
233
+ t = doc.field("359", ind2: '1').subfield('a').get.value.presence
234
+ creators << '[u.a.]' if t && t.match(/\.\.\.|\[u\.a\.\]/i)
235
+
236
+ # Cleanup
237
+ creators = creators.flatten.compact
238
+ creators = creators.map{ |c| c.delete('<').delete('>') }
239
+ creators = creators.map(&:presence).compact.uniq
240
+ end
241
+
242
+ #
243
+ # Creators and contributors without roles for faceting
244
+ #
245
+ field :creator_contributor_facet do
246
+ if (creator_contributor_display = ref(:creator_contributor_display)).present?
247
+ creator_contributor_display.map { |creator_contributor| creator_contributor.gsub(/\[.*\]/, '').strip }
248
+ end
249
+ end
250
+
251
+ #
252
+ # Creators and contributors in extended normalized form without roles
253
+ #
254
+ field :creator_contributor_search do
255
+ creators = []
256
+
257
+ # Alle aus dem Display
258
+ creators = creators + ref(:creator_contributor_display)
259
+ # Entferne Sonderfall [u.a.]
260
+ creators.reject!{|e| e == '[u.a.]'}
261
+
262
+ # + Index Felder für Personen
263
+ creators << doc.field('PPE').subfield(['a', 'p']).get.values
264
+
265
+ # + zweiteilige Nebeneintragungen / beigefügte oder enthaltene Werke
266
+ (800..824).step(6) do |f|
267
+ creators << doc.field("#{f}").subfield(['a','p','c','n','b']).get.values
268
+ end
269
+
270
+ # + Index Felder für Körperschaften
271
+ creators << doc.field('PKO').subfield(['a','k','b','e','g']).get.values
272
+
273
+ # Füge alle Teile zusammen
274
+ creators = creators.flatten.compact
275
+ # Lösche Sortierzeichen
276
+ creators = creators.map{ |c| c.delete('<').delete('>') }
277
+ # Prüfe Inhalte auf Existenz und entferne doppelte Einträge
278
+ creators = creators.map(&:presence).compact.uniq
279
+ end
280
+
281
+ #
282
+ # Edition
283
+ #
284
+ field :edition do
285
+ f403_1 = doc.field('403', ind2: '1').subfield('a').get.value
286
+ f403_2 = doc.field('403', ind2: '2').subfield('a').get.value
287
+ f407_1 = doc.field('407', ind2: '1').subfield('a').get.value
288
+ f610_1 = doc.field('610', ind1: '-', ind2: '1').get.value # Fußnote zur Sekundärausgabe (einleitende Wendung)
289
+
290
+ f403_1.presence || f403_2.presence || f407_1.presence || f610_1.presence
291
+ end
292
+
293
+ #
294
+ # Publisher
295
+ #
296
+ field :publisher do
297
+ # Verlagsort
298
+ f410_1 = doc.field('410', ind2: '1').subfield('a').get.value
299
+ f410_2 = doc.field('410', ind2: '2').subfield('a').get.value
300
+ f415_1 = doc.field('415', ind2: '1').subfield('a').get.value
301
+ f415_2 = doc.field('415', ind2: '2').subfield('a').get.value
302
+
303
+ f410 = f410_1.presence or f410_2.presence
304
+ f415 = f415_1.presence or f415_2.presence
305
+
306
+ # Verleger
307
+ f412_1 = doc.field('412', ind2: '1').subfield('a').get.value
308
+ f412_2 = doc.field('412', ind2: '2').subfield('a').get.value
309
+ f417_1 = doc.field('417', ind2: '1').subfield('a').get.value
310
+ f417_2 = doc.field('417', ind2: '2').subfield('a').get.value
311
+
312
+ f412 = f412_1.presence or f412_2.presence
313
+ f417 = f417_1.presence or f417_2.presence
314
+ # ... weitere Verleger in 418 ohne Ortsangabe ignorieren wir
315
+
316
+ publisher = []
317
+ publisher << [f410, f412].map(&:presence).compact.join(' : ')
318
+ publisher << [f415, f417].map(&:presence).compact.join(' : ')
319
+ publisher.map(&:presence).compact.map { |element| element.gsub(/<<|>>/, '') }
320
+ end
321
+
322
+ #
323
+ # Creation date
324
+ #
325
+ field :creationdate do
326
+ f051 = doc.controlfield('051')
327
+ f052 = doc.controlfield('052')
328
+
329
+ f425_a1 = doc.field('425', ind1: 'a', ind2: '1').subfield('a').get.value # Erscheinungsjahr in Sortierform
330
+ f425_b1 = doc.field('425', ind1: 'b', ind2: '1').subfield('a').get.value # Erscheinungsjahr in Sortierform des frühsten Bandes
331
+ f425_c1 = doc.field('425', ind1: 'c', ind2: '1').subfield('a').get.value # Erscheinungsjahr in Sortierform des letzten Bandes
332
+ f425_p1 = doc.field('425', ind1: 'p', ind2: '1').subfield('a').get.value # Erscheinungsjahr in Sortierform eines Tonträgers
333
+ f595 = doc.field('595').get.value # Erscheinungsjahr der Quelle
334
+
335
+ if f595.present?
336
+ f595 # Erscheinungsjahr der Quelle hat Vorrang vor dem eigentlichen Erscheinungsjahr (falls vorhanden)
337
+ elsif %w(n t).include?(f051.at(0)) or %w(r p).include?(f052.at(0)) # es handelt sich um eine Überordnung
338
+ if f425_b1.present? and f425_c1.present?
339
+ if f425_b1 == f425_c1
340
+ f425_b1
341
+ else
342
+ "#{f425_b1} – #{f425_c1}"
343
+ end
344
+ elsif f425_b1.present? and not f425_c1.present?
345
+ "#{f425_b1} –"
346
+ elsif f425_c1.present? and not f425_b1.present?
347
+ "– #{f425_c1}"
348
+ else
349
+ f425_a1.presence || f425_p1.presence
350
+ end
351
+ else
352
+ f425_a1.presence || f425_p1.presence
353
+ end
354
+ end
355
+
356
+ field :creationdate_search do
357
+ date = ref(:creationdate)
358
+ if date.present?
359
+ date.gsub(/[^0-9]/i, '') # Entferne alle nicht numerischen Zeichen
360
+ end
361
+ end
362
+
363
+ #
364
+ # Format
365
+ #
366
+ field :format do
367
+ f433 = doc.field('433', ind2: '1').subfield('a').get.value
368
+ f434 = doc.field('434', ind2: '1').subfield('a').get.values.join(', ')
369
+ f435 = doc.field('435', ind2: '1').subfield('a').get.value
370
+ f437 = doc.field('437', ind2: '1').subfield('a').get.value
371
+ f653 = doc.field('653', ind2: '1').subfield('a').get.values.join(', ')
372
+
373
+ format = f433
374
+ format = merge(format, f434, delimiter: ' : ')
375
+ format = merge(format, f435, delimiter: ' ; ')
376
+ format = merge(format, f437, delimiter: ' + ')
377
+ format = merge(format, f653, delimiter: '.- ')
378
+
379
+ format.presence
380
+ end
381
+
382
+ #
383
+ # Is part of
384
+ #
385
+ field :is_part_of do
386
+ f525 = doc.field('525', ind2: '1').subfield(['p','a']).get.value(join_subfields: ': ')
387
+ f590 = doc.field('590', ind2: '1').subfield('a').get.value
388
+ f591 = doc.field('591', ind2: '1').subfield('a').get.value
389
+ f592 = doc.field('592', ind2: '1').subfield('a').get.value
390
+ f593 = doc.field('593', ind2: '1').subfield('a').get.value
391
+ f594 = doc.field('594', ind2: '1').subfield('a').get.value
392
+ f595 = doc.field('595', ind2: '1').subfield('a').get.value
393
+ f596 = doc.field('596', ind2: '1').subfield('a').get.value
394
+ f597 = doc.field('597', ind2: '1').subfield('a').get.value
395
+ f598 = doc.field('598', ind2: '1').subfield('a').get.value
396
+
397
+ #f599_1 = doc.datafield('599', ind1: 'a,b', ind2: '1', subfield: 'a', multiple: true).join(' ') # ISSN
398
+ #f599_2 = doc.datafield('599', ind1: 'c,d', ind2: '1', subfield: 'a', multiple: true).join(' ') # ISBN
399
+ #f599_3 = doc.datafield('599', ind1: 'e,f', ind2: '1', subfield: 'a', multiple: true).join(' ') # ISMN
400
+ #f599_4 = doc.datafield('599', ind1: 'g,h', ind2: '1', subfield: 'a', multiple: true).join(' ') # ISRN
401
+
402
+ ipo = f525
403
+ ipo = merge(ipo, f590, delimiter: '.- ', wrap: "In: @" )
404
+ ipo = merge(ipo, f591, delimiter: ' / ' )
405
+ ipo = merge(ipo, f592, delimiter: '. ' )
406
+ ipo = merge(ipo, f593, delimiter: '.- ' )
407
+ ipo = merge(ipo, f594, delimiter: '.- ' )
408
+ ipo = merge(ipo, f595, delimiter: ', ' )
409
+ ipo = merge(ipo, f596, delimiter: '.- ' )
410
+ ipo = merge(ipo, f597, delimiter: '.- ', wrap: "(@)" )
411
+ ipo = merge(ipo, f598, delimiter: '.- ' )
412
+
413
+ #ipo = merge(ipo, f599_1, delimiter: '.- ', wrap: "ISSN @")
414
+ #ipo = merge(ipo, f599_2, delimiter: '.- ', wrap: "ISSN @")
415
+ #ipo = merge(ipo, f599_3, delimiter: '.- ', wrap: "ISMN @")
416
+ #ipo = merge(ipo, f599_4, delimiter: '.- ', wrap: "ISRN @")
417
+
418
+ ipo.presence
419
+ end
420
+
421
+ #
422
+ # ISBN
423
+ #
424
+ field :isbn do
425
+ isbns = []
426
+ isbns << doc.field('540', ind1: '-z', ind2: '1').subfield('a').get.values
427
+ isbns << doc.field('634', ind1: '-z', ind2: '1').subfield('a').get.values
428
+ isbns << doc.field('086', ind2: '1').subfield(['b','c','d']).get.values
429
+ isbns.flatten.map{|v| v.gsub(/[^0-9\-x]/i, '').strip if v.present?}.map(&:presence).compact.uniq
430
+ end
431
+
432
+ #
433
+ # ISSN
434
+ #
435
+ field :issn do
436
+ issns = []
437
+ issns << doc.field('542', ind1: '-z', ind2: '1').subfield('a').get.values
438
+ issns << doc.field('635', ind1: '-z', ind2: '1').subfield('a').get.values
439
+ issns << doc.field('545', ind2: '1').subfield(['a','b','c','d']).get.values
440
+ issns.flatten.map{|v| v.gsub(/[^0-9\-x]/i, '').strip if v.present?}.map(&:presence).compact.uniq
441
+ end
442
+
443
+ #
444
+ # ZDB ID
445
+ #
446
+ field :zdb_id do
447
+ zdb_ids = []
448
+ zdb_ids << doc.field('025', ind1: 'z', ind2: '1').subfield('a').get.values
449
+ zdb_ids.flatten.map(&:presence).compact.uniq
450
+ end
451
+
452
+ #
453
+ # Subject
454
+ #
455
+ field :subject do
456
+ subjects = []
457
+
458
+ subjects << doc.field('902').subfield(['a','p','k','s','g','e','t']).get.values
459
+
460
+ # Beispiel aus 740: New York (N.Y.)--Social life and customs--20th century--Fiction.
461
+ %w(710 711 740).each do |f|
462
+ t = doc.field(f).subfield('a').get.values
463
+ t = t.flatten.map(&:presence).compact
464
+ t = t.map{|a| a.split('--')}.flatten.map{|s| s.end_with?('.') ? s[0..-2].strip : s}.map(&:presence).compact.uniq
465
+ subjects = subjects + t
466
+ end
467
+
468
+ subjects.flatten.map(&:presence).compact.map{|f| f.delete('<').delete('>')}.uniq
469
+ end
470
+
471
+ field :subject_search do
472
+ subjects = []
473
+
474
+ # Alles Display subjects
475
+ subjects << ref(:subject)
476
+
477
+ # + Index Felder für weitere Schlagworte
478
+ subjects << doc.field('PSW').subfield(['a','k','e','g','s','p','t','f','z']).get.values
479
+
480
+ subjects.flatten.map(&:presence).compact.map{|f| f.delete('<').delete('>')}.uniq
481
+ end
482
+
483
+ #
484
+ # DDC
485
+ #
486
+ field :ddc do
487
+ ddc_fields = []
488
+ ddc_fields << doc.field('700', ind1: 'b', ind2: '1').subfield('a').get.values
489
+ ddc_fields << doc.field('705', ind1: ' ', ind2: '1').subfield('a').get.values
490
+
491
+ ddc_fields.flatten.map(&:presence).compact.uniq
492
+ end
493
+
494
+ #
495
+ # Description
496
+ #
497
+ field :description do
498
+ descriptions = []
499
+
500
+ # 405 - Erscheinungsverlauf von Zeitschriften
501
+ descriptions << doc.field('405', ind2: '1').subfield(['a', 'p']).get.values(join_subfields: ': ')
502
+
503
+ # 522 - Teilungsvermerk bei fortlaufenden Sammelwerken
504
+ descriptions << doc.field('522', ind2: '1').subfield(['a', 'p']).get.values(join_subfields: ': ')
505
+
506
+ # 523 - Erscheinungsverlauf von Monos
507
+ descriptions << doc.field('523', ind2: '1').subfield(['a', 'p']).get.values(join_subfields: ': ')
508
+
509
+ (501..519).each do |f|
510
+ descriptions << doc.field("#{f}", ind2: '1').subfield(['a', 'p']).get.values(join_subfields: ': ')
511
+ end
512
+
513
+ (536..537).each do |f|
514
+ descriptions << doc.field("#{f}", ind2: '1').subfield(['a', 'p']).get.values(join_subfields: ': ')
515
+ end
516
+
517
+ # Finally...
518
+ descriptions.flatten.map(&:presence).compact.uniq
519
+ end
520
+
521
+ #
522
+ # Abstracts
523
+ #
524
+ field :abstract do
525
+ abstracts = []
526
+
527
+ abstracts << doc.field('750').subfield('a').get.value
528
+ abstracts << doc.field('753').subfield('a').get.value
529
+ abstracts << doc.field('756').subfield('a').get.value
530
+
531
+ abstracts.map(&:presence).compact
532
+ end
533
+
534
+ #
535
+ # Language
536
+ #
537
+ field :language do
538
+ languages = []
539
+ languages << doc.field('037', ind1: 'b', ind2: ['1','2']).subfield('a').get.values
540
+ languages.flatten.map(&:presence).compact.uniq
541
+ end
542
+
543
+ #
544
+ # Relation
545
+ #
546
+ field :relation do
547
+ relations = []
548
+
549
+ if (f021a = doc.field('021').subfield('a').get.value).present?
550
+ relations << {
551
+ ht_number: f021a,
552
+ label: 'Primärform'
553
+ }
554
+ end
555
+
556
+ (526..534).each do |mab_field_number|
557
+ doc.field("#{mab_field_number}", ind2: '1').get.fields.each do |field|
558
+ ht_number = field.get_subfield('9').try(:value).presence
559
+ label = [
560
+ field.get_subfield('p').try(:value).presence,
561
+ field.get_subfield('a').try(:value).try(:gsub, /<<|>>/, '').presence
562
+ ].compact.join(' ')
563
+
564
+ relations << {ht_number: ht_number, label: label} if label
565
+ end
566
+ end
567
+
568
+ relations.flatten.select { |relation| relation[:label].present? }.map(&:to_json)
569
+ end
570
+
571
+ #
572
+ # JSON encoded field to store superorder related informations
573
+ #
574
+ field :superorder_display do
575
+ superorders = []
576
+
577
+ # Link zur Überordung eines mehrbändigen Werkes
578
+ superorders << {
579
+ ht_number: doc.field('010', ind2: '1').subfield('a').get.value,
580
+ label: doc.field('331', ind2: '2').subfield('a').get.value,
581
+ volume_count: doc.field('089', ind2: '1').subfield('a').get.value # Bandzählung dieses Werkes innerhalb der entsprechenden Überordnung
582
+ }
583
+
584
+ # 451 ff
585
+ (451..491).step(10) do |f|
586
+ superorders << {
587
+ ht_number: doc.field("#{f+2}", ind2: '1').subfield('a').get.value,
588
+ label: [doc.field("#{f}", ind2: '1').subfield('a').get.value, doc.field("#{f}", ind2: '2').subfield('a').get.value].compact.reject { |label| label[/\A\.\.\.\s+(;|:)/] }.first,
589
+ volume_count: doc.field("#{f+4}", ind2: '1').subfield('a').get.value
590
+ }
591
+ end
592
+
593
+ superorders
594
+ .map(&:presence)
595
+ .delete_if { |element| element[:ht_number].blank? }
596
+ .each do |element|
597
+ # remove 'not sort' indicators from label
598
+ element[:label].try(:gsub!, /<<|>>/, '')
599
+
600
+ # remove leading '... ' from label
601
+ element[:label].try(:gsub!, /\A\.\.\.\s+/, '')
602
+
603
+ # get label additions (everything behind the first ':') and make it a clean array
604
+ element[:label_additions] = if element[:label].present?
605
+ element[:label][/:.*/]
606
+ .try(:gsub, /(\A:)|(,\Z)/, '')
607
+ .try(:strip)
608
+ .try(:gsub, /,/, ';')
609
+ .try(:split, ';')
610
+ .try(:map, &:strip)
611
+ end
612
+
613
+ # remove every label addition that is also in volume count (space removement and downcasing are done for more fuzzy matching e.g. between 'Faz. 4' and 'faz.4'
614
+ if element[:label_additions].present? && element[:volume_count].present?
615
+ volume_count_elements = element[:volume_count].gsub(/,|:|;/, ';').split(';').map { |e| e.gsub(/\s+/, '').downcase } # volume_count elements without spaces for more fuzzy comparing
616
+
617
+ element[:label_additions].reject! { |label_addition| volume_count_elements.include? label_addition.gsub(/\s+/, '').downcase }
618
+ element[:label_additions].reject! { |label_addition| ['bd', 'band'].any? { |forbidden_label_addition| label_addition.downcase.starts_with? forbidden_label_addition } } # additional remove every Bd. or Band
619
+ element[:label_additions] = element[:label_additions].presence
620
+ end
621
+
622
+ # remove any label additions from the label
623
+ element[:label].try(:gsub!, /:.*\Z/, '')
624
+ element[:label].try(:gsub!, /;.*\Z/, '')
625
+ element[:label].try(:strip!)
626
+
627
+ element[:volume_count].try(:gsub!, /<.*>/, '')
628
+ end.uniq.map(&:to_json)
629
+ end
630
+
631
+ #
632
+ # Linked superorders (only ht_numbers) + ht_number if primary form (if any)
633
+ #
634
+ # @depends_on: superorder_display
635
+ #
636
+ field :superorder do
637
+ superorders = []
638
+
639
+ f623 = doc.field('623').get.value # Identifikationsnummer des 1. GT der Sekundärform
640
+ f629 = doc.field('629').get.value # Identifikationsnummer des 2. GT der Sekundärform
641
+
642
+ superorders << if (json_encoded_superorders_display = ref(:superorder_display)).present?
643
+ superorders_display = json_encoded_superorders_display.map { |json_encoded_superorder_display| JSON.parse(json_encoded_superorder_display) }
644
+ superorders_display.map { |superorder_display| superorder_display['ht_number'] }
645
+ end
646
+
647
+ superorders << f623 if f623.present?
648
+ superorders << f629 if f629.present?
649
+
650
+ superorders.flatten.map(&:presence).compact
651
+ end
652
+
653
+ #
654
+ # Sind wir eine Überordnung?
655
+ #
656
+ field :is_superorder do
657
+ f051 = doc.controlfield('051')
658
+ f052 = doc.controlfield('052')
659
+
660
+ f051.at(0) == 'n' || f051.at(0) == 't' || f052.at(0) == 'p' || f052.at(0) == 'r' || f052.at(0) == 'z'
661
+ end
662
+
663
+ #
664
+ # Sind wir ein Band?
665
+ #
666
+ field :is_suborder do
667
+ ref(:superorder_display).present? # we take superorder_display instead of superorder to exclude superorder relations between primary/secondare form from this indicator
668
+ end
669
+
670
+ #
671
+ # Erscheinungsform
672
+ #
673
+ field :erscheinungsform do
674
+ f051 = doc.controlfield('051')
675
+ f052 = doc.controlfield('052')
676
+ f051s = f051.join.slice(1..3) || ""
677
+ f052s = f052.join.slice(1..6) || ""
678
+
679
+ type = case
680
+ when (f051.at(0) == 'a') then 'article'
681
+ when (f051.at(0) == 'm') then 'monograph'
682
+ when (f051.at(0) == 'n') then 'monograph'
683
+ when (f051.at(0) == 's') then 'monograph'
684
+
685
+ when (f052.at(0) == 'a') then 'article'
686
+ when (f052.at(0) == 'p') then 'journal'
687
+ when (f052.at(0) == 'r') then 'series'
688
+ when (f052.at(0) == 'z') then 'newspaper'
689
+
690
+ when (f051s.include?('t')) then 'article'
691
+ when (f052s.include?('au')) then 'article'
692
+ when (f052s.include?('se')) then 'series'
693
+ # ... der Rest
694
+ else
695
+ #
696
+ # Hack to make all suborders without proper 'erscheinungsform' monographs
697
+ #
698
+ if ref(:is_suborder).presence
699
+ 'monograph'
700
+ else
701
+ 'other'
702
+ end
703
+ end
704
+
705
+ type
706
+ end
707
+
708
+ #
709
+ # Delivery Catagory
710
+ #
711
+ field :delivery_category do
712
+ materialtyp = ref(:materialtyp)
713
+ erscheinungsform = ref(:erscheinungsform)
714
+
715
+ if (materialtyp == 'online_resource')
716
+ 'electronic_resource'
717
+ elsif (erscheinungsform == 'series' || erscheinungsform == 'journal')
718
+ 'structural_metadata'
719
+ else
720
+ 'physical_item'
721
+ end
722
+ end
723
+
724
+ field :volume_count_sort do
725
+ possible_values = []
726
+ possible_values << doc.field('090', ind2: '1').subfield('a').get.value
727
+ (451..491).step(10) { |f| possible_values << doc.field("#{f+5}", ind2: '1').subfield('a').get.value }
728
+ count = possible_values.map(&:presence).compact.uniq.first
729
+ count.rjust(15, '0') if count.present?
730
+ end
731
+
732
+ #
733
+ # Notation
734
+ #
735
+ field :notation do
736
+ doc.field('700', ind2: ' ').subfield('a').get.values(join_subfields: true)
737
+ end
738
+
739
+ field :notation_sort do
740
+ ref(:notation).try(:last)
741
+ end
742
+
743
+ #
744
+ # Table of contents
745
+ #
746
+ field :toc do
747
+ doc.field('TXT').subfield('a').get.values.join(' ')
748
+ end
749
+
750
+ #
751
+ # Signature
752
+ #
753
+ field :signature do
754
+ signatures = []
755
+
756
+ # Lade LOC Felder für Signaturen-Extraktion
757
+ fields = doc.field('LOC').subfield(['b','d','5']).get.fields.presence || []
758
+ # Lösche alle Felder die kein Unterfeld d haben (ausgesondert)
759
+ fields = fields.reject{|f| f.subfields.find{|sf| sf.name == "d"}.blank?}
760
+ # Prüfe ob alle Exemplare im Magazin stehen
761
+ all_stack = fields.map{|f| f.subfields.find {|sf| sf.name == 'b' && sf.value.match(/02|03|04|07/)}.present?}.all?
762
+
763
+ # Zeitschriftensignatur (haben Vorrgang, falls vorhanden)
764
+ signatures << doc.field('200', ind2: ' ').subfield('f').get.value.try(:gsub, ' ', '')
765
+
766
+ # Wenn alle Exemplare im Magzin stehen, dann nimm nur die erste signatur
767
+ if all_stack
768
+ fields.each do |field|
769
+ subfield = field.subfields.find{|f| f.name == "d"}
770
+ if subfield.present? && subfield.value.present?
771
+ signatures << subfield.value
772
+ break
773
+ end
774
+ end
775
+ # ansonsten extrahiere aus den normalen Signaturen eine Basis-Signatur
776
+ else
777
+ # Lösche alle Felder die als Standordkennziffer eine Magazinkennung haben
778
+ fields = fields.reject{|f| f.subfields.find{|sf| sf.name == 'b' && sf.value.match(/02|03|04|07/)}.present?}
779
+
780
+ # Sortiere die restlichen Felder nach Unterfeld 5 (Strichcode)
781
+ fields = fields.sort do |x, y|
782
+ x5 = x.subfields.find{|f| f.name == "5"}
783
+ y5 = y.subfields.find{|f| f.name == "5"}
784
+ if x5 && y5
785
+ x5.value <=> y.value
786
+ else
787
+ 0
788
+ end
789
+ end
790
+
791
+ # Extrahiere die Signaturen aus Unterfeld d und erzeuge eine Basis-Signatur
792
+ fields.each do |field|
793
+ subfield = field.subfields.find{|f| f.name == "d"}
794
+ if subfield.present? && subfield.value.present?
795
+ signature = subfield.value
796
+ index = signature.index('+') || signature.length
797
+ base_signature = signature[0..index-1]
798
+ signatures << base_signature
799
+ end
800
+ end
801
+ end
802
+
803
+ # Stücktitel Signatur
804
+ signatures << doc.field('100', ind2: ' ').subfield('a').get.value
805
+
806
+ # Fertig. Wir nehmen die erste Signatur zur Anzeige
807
+ signatures.flatten.map(&:presence).compact.uniq.first
808
+ end
809
+
810
+ field :signature_search do
811
+ signatures = []
812
+ signatures = signatures + doc.field('LOC').subfield('d').get.values
813
+ # Stücktitel Signatur
814
+ signatures << doc.field('100', ind2: ' ').subfield('a').get.value
815
+ # Zeitschriftensignatur
816
+ signatures << doc.field('200', ind2: ' ').subfield('f').get.value
817
+
818
+ signatures.flatten.map(&:presence).compact.map do |signature|
819
+ _signature = signature
820
+ .gsub(/\A\//, '') # remove leading '/' for some journal signatures
821
+ .gsub(/\s+/, '') # remove spaces for some journal signatures (e.g. 'P 10/34 t 26')
822
+ .upcase # upcase signatures like 'P10/34t26' to 'P10/34T26' to detect duplicates like 34t26 and 34T26 (search engine should handle downcasing, primo does)
823
+
824
+ # for signatures with volume count e.g. 'LKL2468-14/15', add all variants possible ['LKL2468-14/15', 'LKL2468-14', 'LKL2468']
825
+ _signature_array = [_signature, _signature.gsub(/(\d+)\/\d+\Z/, '\1'), _signature.gsub(/\-\d+.*\Z/, '')]
826
+
827
+ # for journals which only have one single signature with leading 'Pxx/' like 'P10/34M3' create 'Pxx/'-less version also
828
+ _signature_array.push _signature.gsub(/\AP\d+\//, '')
829
+ end.flatten.uniq
830
+ end
831
+
832
+ #
833
+ # Link to resource
834
+ #
835
+ # In u steht die URL, in 3, x, z können Beschreibungen stehen.
836
+ # 3 - Information über die Art. Hier kann man z.B. Inhaltsverzeichnisse erkennen
837
+ # x - "Verlag"
838
+ # z - Zugriffsinformationen (z.B. Nur im Campusnetz)
839
+ field :resource_link do
840
+ fulltext_links = []
841
+
842
+ links = doc.field('655').subfield(['u', '3', 'z', 't']).get
843
+ links.each do |link|
844
+ url = link.get_subfield('u').try(:value)
845
+ subfield_3 = link.get_subfield('3') # HBZ Inhaltsverzeichnisse
846
+ subfield_z = link.get_subfield('z') # BVB Inhaltsverzeichnisse
847
+ subfield_t = link.get_subfield('t') # Type: VIEW => Adam Inhaltsverzeichnis
848
+
849
+ unless (url.present? && subfield_3.present? && subfield_3.value =~ /^inhalt/i) ||
850
+ (url.present? && subfield_z.present? && subfield_z.value =~ /^inhalt/i) ||
851
+ (url.present? && subfield_t.present? && subfield_t.value =~ /^view/i)
852
+ fulltext_links << url
853
+ end
854
+ end
855
+
856
+ fulltext_links.compact.presence
857
+ end
858
+
859
+ #
860
+ # Link to TOC
861
+ #
862
+ field :link_to_toc do
863
+ toc_links = []
864
+
865
+ links = doc.field('655').subfield(['u', '3', 'z', 't']).get
866
+ links.each do |link|
867
+ url = link.get_subfield('u').try(:value)
868
+ subfield_3 = link.get_subfield('3') # HBZ Inhaltsverzeichnisse
869
+ subfield_z = link.get_subfield('z') # BVB Inhaltsverzeichnisse
870
+ subfield_t = link.get_subfield('t') # Type: VIEW => Adam Inhaltsverzeichnis
871
+
872
+ if (url.present? && subfield_3.present? && subfield_3.value =~ /^inhaltsv/i) ||
873
+ (url.present? && subfield_z.present? && subfield_z.value =~ /^inhaltsv/i) ||
874
+ (url.present? && subfield_t.present? && subfield_t.value =~ /^view/i)
875
+ toc_links << url
876
+ end
877
+ end
878
+
879
+ toc_links.compact.presence
880
+ end
881
+
882
+ #
883
+ # Selektionskennzeichen
884
+ #
885
+ field :selection_code do
886
+ codes = []
887
+ codes << doc.field('078', ind1: ['e', 'r']).subfield('a').get.values
888
+
889
+ codes.flatten.map(&:presence).compact.uniq
890
+ end
891
+
892
+ #
893
+ # Bestandsinformationen Zeitschriften
894
+ #
895
+ field :ldsX do
896
+ # Feld 200 mit ind1 = ' ', ind2 = ' '
897
+ # Unterfelder:
898
+ # 0 - Sortierindikator
899
+ # a - Einleitende Wendung
900
+ # b - Verlauf
901
+ # c - Lücke im Bestand / Verlauf
902
+ # e - Kommentar
903
+ # f - Signatur
904
+ r = []
905
+
906
+ fields = doc.field('200', ind2: ' ').subfield(['0', 'a', 'b', 'c', 'e', 'f']).get
907
+ fields.each do |field|
908
+ field_0 = field.get_subfield('0')
909
+ field_a = field.get_subfield('a')
910
+ field_b = field.get_subfield('b')
911
+ field_c = field.get_subfield('c')
912
+ field_e = field.get_subfield('e')
913
+ field_f = field.get_subfield('f')
914
+
915
+ s = ""
916
+ s = merge(s, field_a.try(:value), delimiter: ' ')
917
+ s = merge(s, field_b.try(:value), delimiter: ': ')
918
+ s = merge(s, field_c.try(:value), delimiter: ' ')
919
+ s = merge(s, field_e.try(:value), delimiter: '. ')
920
+ s = merge(s, field_f.try(:value), delimiter: ' <strong>Zeitschriftensignatur</strong>: ')
921
+
922
+ # Cleanup
923
+ s = s.gsub(/^\- /, '') # Z.b. "- Index: Foo Bar"
924
+
925
+ # Sort
926
+ position = nil
927
+ if field_0.present?
928
+ position = ((field_0.value || "").match(/^(\d+)$/) && $1.to_i) || nil
929
+ end
930
+
931
+ if position && position.is_a?(Fixnum)
932
+ r[position] = s
933
+ else
934
+ r << s
935
+ end
936
+ end
937
+
938
+ r.map(&:presence).compact.uniq
939
+ end
940
+
941
+
942
+ #
943
+ # Frbr t
944
+ #
945
+ field :frbr_t do
946
+ value = 1
947
+ f052 = doc.controlfield('052')
948
+ ffmt = doc.controlfield('FMT')
949
+ f100 = doc.field('100').subfield(['a','p']).get.value
950
+ f200 = doc.field('200').subfield(['a','k','g','e']).get.value
951
+ f300 = doc.field('300', ind2: '2').subfield('a').get.value
952
+
953
+ if (f052.present? and ['p','z','r','j'].include?(f052.at(0)))
954
+ value = 99
955
+ elsif (ffmt == 'MU' and f300.present?)
956
+ value = 99
957
+ elsif (ffmt == 'MU' and f100.blank? and f200.blank?)
958
+ value = 99
959
+ end
960
+
961
+ value
962
+ end
963
+
964
+ #
965
+ # Frbr k1 (ohne Körperschaften zunächst)
966
+ #
967
+ field :frbr_k1 do
968
+ value = nil
969
+ ffmt = doc.controlfield('FMT')
970
+ f052 = doc.controlfield('052')
971
+ f334 = doc.field('334', ind2: '1').subfield('a').get.value.try(:downcase)
972
+ f100_1 = doc.naco_normalization(doc.field('100', ind1: '-', ind2: '1').subfield(['a','p']).get.value).presence
973
+ f100_2 = doc.naco_normalization(doc.field('100', ind1: 'b', ind2: '1').subfield(['a','p']).get.value).presence
974
+
975
+ if (f100_1.present?)
976
+ value = "$$Kpad#{f100_1}$$AA"
977
+ elsif (f100_2.present?)
978
+ value = "$$Kpad#{f100_2}$$AA"
979
+ elsif (f100_2.blank? and ffmt == 'MU')
980
+ value = "$$Kpad#{f100_2}$$AA"
981
+ elsif (f100_1.blank? and ffmt == 'MH' and f052.empty? and f334 == "elektronische ressource")
982
+ value = "$$Kpad#{f100_2}$$AA"
983
+ end
984
+
985
+ value
986
+ end
987
+
988
+ field :redactional_remark do
989
+ doc.field("537", ind2: '1').subfield(['a', 'p']).get.values(join_subfields: ': ').presence.try(:join)
990
+ end
991
+
992
+ #
993
+ # Sekundärformen
994
+ #
995
+ field :is_secondary_form do
996
+ (doc.field('610').get.value || doc.field('611').get.value || doc.field('619').get.value || doc.field('621').get.value) != nil
997
+ end
998
+
999
+ field :secondary_form_preliminary_phrase do
1000
+ doc.field('610', ind1: '-', ind2: '1').get.value
1001
+ end
1002
+
1003
+ field :secondary_form_publisher do
1004
+ (doc.field('611').get.value.to_s << ' : ' << doc.field('613').get.value.to_s).gsub(/\A : /, '').presence
1005
+ end
1006
+
1007
+ field :secondary_form_creationdate do
1008
+ doc.field('619').get.value
1009
+ end
1010
+
1011
+ field :secondary_form_isbn do
1012
+ doc.field('634').get.value
1013
+ end
1014
+
1015
+ field :secondary_form_physical_description do
1016
+ doc.field('637').get.value
1017
+ end
1018
+
1019
+ # there can at most be two of 'em
1020
+ field :secondary_form_superorder do
1021
+ [
1022
+ {
1023
+ ht_number: doc.field('623').get.value,
1024
+ label: doc.field('621').get.value,
1025
+ volume_count: doc.field('625').get.value
1026
+ },
1027
+ {
1028
+ ht_number: doc.field('629').get.value,
1029
+ label: doc.field('627').get.value,
1030
+ volume_count: doc.field('631').get.value
1031
+ }
1032
+ ].select { |superorder| superorder[:label].present? }.map(&:to_json).presence
1033
+ end
1034
+
1035
+ #
1036
+ # doc
1037
+ #
1038
+
1039
+ # a complex data structure to be stored by the search engine
1040
+ field :doc do
1041
+ doc = {
1042
+ :redactional_remark => ref(:redactional_remark)
1043
+ }
1044
+ .inject({}) { |hash, (key, value)| hash[key] = value if value.present?; hash }
1045
+
1046
+ doc.to_json if doc.present?
1047
+ end
1048
+
1049
+ end
1050
+ end