Commit 1a09f438 authored by Jonas Waeber's avatar Jonas Waeber
Browse files

Documents now retrieve the record set name and institution names.

parent 235805bb
Pipeline #24670 passed with stages
in 5 minutes and 7 seconds
...@@ -30,6 +30,7 @@ import org.memobase.builders.PersonFacetBuilder ...@@ -30,6 +30,7 @@ import org.memobase.builders.PersonFacetBuilder
import org.memobase.builders.PlaceFacetBuilder import org.memobase.builders.PlaceFacetBuilder
import org.memobase.builders.SuggestContainerBuilder import org.memobase.builders.SuggestContainerBuilder
import org.memobase.helpers.AspectRatio import org.memobase.helpers.AspectRatio
import org.memobase.helpers.ElasticSearchWrapper
import org.memobase.helpers.Extract import org.memobase.helpers.Extract
import org.memobase.helpers.FacetBuildHelpers import org.memobase.helpers.FacetBuildHelpers
import org.memobase.helpers.Filter import org.memobase.helpers.Filter
...@@ -39,11 +40,13 @@ import org.memobase.helpers.KEYS ...@@ -39,11 +40,13 @@ import org.memobase.helpers.KEYS
import org.memobase.helpers.TranslationMappers import org.memobase.helpers.TranslationMappers
import org.memobase.model.DocumentsSearchDoc import org.memobase.model.DocumentsSearchDoc
import org.memobase.model.EnrichedDigitalMetadata import org.memobase.model.EnrichedDigitalMetadata
import org.memobase.model.FacetContainer
import org.memobase.model.LanguageContainer import org.memobase.model.LanguageContainer
import org.memobase.model.Schema import org.memobase.model.Schema
class DocumentsSearchDocBuilder( class DocumentsSearchDocBuilder(
private val translationMappers: TranslationMappers, private val translationMappers: TranslationMappers,
private val elasticSearchWrapper: ElasticSearchWrapper,
private val mediaUrl: String private val mediaUrl: String
) { ) {
private val log = LogManager.getLogger("SearchDocTransform") private val log = LogManager.getLogger("SearchDocTransform")
...@@ -213,6 +216,8 @@ class DocumentsSearchDocBuilder( ...@@ -213,6 +216,8 @@ class DocumentsSearchDocBuilder(
} }
} }
val recordSetId = extractRecordSet(record)
return DocumentsSearchDoc( return DocumentsSearchDoc(
title = Extract.typedEntityByType(recordTitles, "type", "main", "title"), title = Extract.typedEntityByType(recordTitles, "type", "main", "title"),
seriesTitle = Extract.typedEntityByType(recordTitles, "type", "series", "title"), seriesTitle = Extract.typedEntityByType(recordTitles, "type", "series", "title"),
...@@ -233,10 +238,20 @@ class DocumentsSearchDocBuilder( ...@@ -233,10 +238,20 @@ class DocumentsSearchDocBuilder(
sameAs = Extract.listOfStrings(record["sameAs"]), sameAs = Extract.listOfStrings(record["sameAs"]),
abstract = Extract.languageContainer("abstract (record id: $key)", record["abstract"]), abstract = Extract.languageContainer("abstract (record id: $key)", record["abstract"]),
recordId = key, recordId = key,
institution = extractInstitution(record), institution = extractInstitution(record).map { value -> elasticSearchWrapper.getInstitutionName(value) },
recordSet = extractRecordSet(record), recordSet = FacetContainer(
descriptiveNote = Extract.languageContainer("descriptiveNote (record id: $key)", record["descriptiveNote"]), elasticSearchWrapper.getRecordSetName(recordSetId),
scopeAndContent = Extract.languageContainer("scopeAndContent (record id: $key)", record["scopeAndContent"]), null,
if (recordSetId != "") listOf(recordSetId) else emptyList()
),
descriptiveNote = Extract.languageContainer(
"descriptiveNote (record id: $key)",
record["descriptiveNote"]
),
scopeAndContent = Extract.languageContainer(
"scopeAndContent (record id: $key)",
record["scopeAndContent"]
),
relatedMaterial = Extract.languageContainer("relation (record id: $key)", record["relation"]), relatedMaterial = Extract.languageContainer("relation (record id: $key)", record["relation"]),
source = Extract.languageContainer("source (record id: $key)", record["source"]), source = Extract.languageContainer("source (record id: $key)", record["source"]),
temporal = temporalBuilder.build(), temporal = temporalBuilder.build(),
...@@ -315,12 +330,16 @@ class DocumentsSearchDocBuilder( ...@@ -315,12 +330,16 @@ class DocumentsSearchDocBuilder(
"physicalCharacteristics", "physicalCharacteristics",
physicalObject?.get("physicalCharacteristics") physicalObject?.get("physicalCharacteristics")
), ),
physicalObjectNote = Extract.languageContainer("descriptiveNote", physicalObject?.get("descriptiveNote")), physicalObjectNote = Extract.languageContainer(
"descriptiveNote",
physicalObject?.get("descriptiveNote")
),
usageConditionsPhysical = Extract.languageContainer( usageConditionsPhysical = Extract.languageContainer(
"conditionsOfUse", "conditionsOfUse",
physicalObject?.get("conditionsOfUse") physicalObject?.get("conditionsOfUse")
), ),
usagePhysical = Extract.typedEntityByType(physicalRules, "type", "usage", "sameAs").flatMap { it.toList() }, usagePhysical = Extract.typedEntityByType(physicalRules, "type", "usage", "sameAs")
.flatMap { it.toList() },
callNumber = Extract.typedEntityByType(physicalIdentifiers, "type", "callNumber", "identifier") callNumber = Extract.typedEntityByType(physicalIdentifiers, "type", "callNumber", "identifier")
.flatMap { it.toList() }, .flatMap { it.toList() },
published = (record[KEYS.isPublished] as Boolean?) ?: false, published = (record[KEYS.isPublished] as Boolean?) ?: false,
......
...@@ -53,7 +53,7 @@ class KafkaTopology( ...@@ -53,7 +53,7 @@ class KafkaTopology(
private val updateTopic = appSettings.getProperty(SettingsProps.updateTopic) private val updateTopic = appSettings.getProperty(SettingsProps.updateTopic)
private val reportTopic = settings.processReportTopic private val reportTopic = settings.processReportTopic
private val documentSearchDocBuilder = DocumentsSearchDocBuilder(translationMappers, mediaUrl) private val documentSearchDocBuilder = DocumentsSearchDocBuilder(translationMappers, elasticSearchWrapper, mediaUrl)
private val institutionSearchDoc = InstitutionSearchDocBuilder(translationMappers, elasticSearchWrapper) private val institutionSearchDoc = InstitutionSearchDocBuilder(translationMappers, elasticSearchWrapper)
private val updateQueryBuilder = UpdateQueryBuilder() private val updateQueryBuilder = UpdateQueryBuilder()
......
...@@ -20,8 +20,6 @@ package org.memobase.helpers ...@@ -20,8 +20,6 @@ package org.memobase.helpers
import ch.memobase.rdf.NS import ch.memobase.rdf.NS
import com.beust.klaxon.JsonObject import com.beust.klaxon.JsonObject
import org.apache.logging.log4j.LogManager import org.apache.logging.log4j.LogManager
import org.memobase.model.FacetContainer
import org.memobase.model.LanguageContainer
/** /**
* Extraction helpers for institutions and record sets. * Extraction helpers for institutions and record sets.
...@@ -29,40 +27,30 @@ import org.memobase.model.LanguageContainer ...@@ -29,40 +27,30 @@ import org.memobase.model.LanguageContainer
object InstitutionAndRecordSetExtractionHelper { object InstitutionAndRecordSetExtractionHelper {
private val log = LogManager.getLogger("InstitutionAndRecordSetExtractionHelper") private val log = LogManager.getLogger("InstitutionAndRecordSetExtractionHelper")
fun extractInstitution(record: JsonObject): List<FacetContainer> { fun extractInstitution(record: JsonObject): List<String> {
val containers = extract(KEYS.heldBy, record) val institutionIds = extract(KEYS.heldBy, record)
return if (containers.isNotEmpty()) { return if (institutionIds.isNotEmpty()) {
containers institutionIds
} else { } else {
listOf(FacetContainer.placeholder("NoInstitutionInRecord")) emptyList()
} }
} }
fun extractRecordSet(record: JsonObject): FacetContainer { fun extractRecordSet(record: JsonObject): String {
val containers = extract(KEYS.isPartOf, record) val values = extract(KEYS.isPartOf, record)
return if (containers.isNotEmpty()) { return if (values.isNotEmpty()) {
containers[0] values[0]
} else { } else {
FacetContainer.placeholder("NoRecordSetInRecord") ""
} }
} }
private fun extract(key: String, record: JsonObject): List<FacetContainer> { private fun extract(key: String, record: JsonObject): List<String> {
return record[key].let { items -> return record[key].let { items ->
when (items) { when (items) {
is String -> listOf( is String -> listOf(removeNamespace(key, items))
FacetContainer(
LanguageContainer(emptyList(), emptyList(), emptyList(), emptyList()),
null,
listOf(removeNamespace(key, items))
)
)
is List<*> -> items.map { item -> is List<*> -> items.map { item ->
FacetContainer( removeNamespace(key, item as String)
LanguageContainer(emptyList(), emptyList(), emptyList(), emptyList()),
null,
listOf(removeNamespace(key, item as String))
)
} }
else -> { else -> {
log.error("No property $key in record ${record[KEYS.entityId]}.") log.error("No property $key in record ${record[KEYS.entityId]}.")
......
...@@ -170,8 +170,8 @@ data class DocumentsSearchDoc( ...@@ -170,8 +170,8 @@ data class DocumentsSearchDoc(
emptyList(), emptyList(),
emptyList(), emptyList(),
emptyList(), emptyList(),
listOf(FacetContainer.placeholder("NoInstitutionInRecord")), emptyList(),
FacetContainer.placeholder("NoRecordSetInRecord"), FacetContainer.EMPTY,
false, false,
emptyList(), emptyList(),
emptyList(), emptyList(),
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
package org.memobase.model package org.memobase.model
import com.fasterxml.jackson.annotation.JsonInclude import com.fasterxml.jackson.annotation.JsonInclude
import org.memobase.model.LanguageContainer.Companion
@JsonInclude(JsonInclude.Include.NON_EMPTY) @JsonInclude(JsonInclude.Include.NON_EMPTY)
data class FacetContainer( data class FacetContainer(
...@@ -27,6 +28,11 @@ data class FacetContainer( ...@@ -27,6 +28,11 @@ data class FacetContainer(
val facet: List<String>? val facet: List<String>?
) { ) {
companion object { companion object {
val EMPTY = FacetContainer(
LanguageContainer.EMPTY,
null,
emptyList()
)
val DEFAULT = FacetContainer( val DEFAULT = FacetContainer(
LanguageContainer.DEFAULT, LanguageContainer.DEFAULT,
null, null,
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
package org.memobase package org.memobase
import io.mockk.every import io.mockk.every
import io.mockk.mockk
import java.io.File import java.io.File
import java.nio.charset.Charset import java.nio.charset.Charset
import java.util.stream.Stream import java.util.stream.Stream
...@@ -31,7 +32,9 @@ import org.junit.jupiter.api.TestInstance ...@@ -31,7 +32,9 @@ import org.junit.jupiter.api.TestInstance
import org.junit.jupiter.api.assertAll import org.junit.jupiter.api.assertAll
import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.MethodSource import org.junit.jupiter.params.provider.MethodSource
import org.memobase.helpers.ElasticSearchWrapper
import org.memobase.model.FacetContainer import org.memobase.model.FacetContainer
import org.memobase.model.FacetContainer.Companion
import org.memobase.model.LanguageContainer import org.memobase.model.LanguageContainer
import org.memobase.params.TestParam import org.memobase.params.TestParam
...@@ -44,13 +47,20 @@ class IntegrationTest { ...@@ -44,13 +47,20 @@ class IntegrationTest {
return File("$resourcePath/$fileName").readText(Charset.defaultCharset()) return File("$resourcePath/$fileName").readText(Charset.defaultCharset())
} }
private val elasticSearchWrapperMocked = run {
val internal = mockk<ElasticSearchWrapper>()
every { internal.getRecordSetName("soz-004") } returns LanguageContainer.placeholder("soz-004")
every { internal.getInstitutionName("soz") } returns FacetContainer.placeholder("soz")
internal
}
@ParameterizedTest @ParameterizedTest
@MethodSource("testParams") @MethodSource("testParams")
fun `integration tests`(params: TestParam) { fun `integration tests`(params: TestParam) {
val settings = App.createSettings("kafkaTest1.yml") val settings = App.createSettings("kafkaTest1.yml")
every { TestUtilities.elasticSearchWrapperMocked.countNumberOfDocuments("") } returns 123 every { elasticSearchWrapperMocked.countNumberOfDocuments("") } returns 123
every { TestUtilities.elasticSearchWrapperMocked.getDocumentTypesFromRecords("", "") } returns listOf( every { elasticSearchWrapperMocked.getDocumentTypesFromRecords("", "") } returns listOf(
FacetContainer( FacetContainer(
LanguageContainer(listOf("Foto"), listOf("Foto"), listOf("Foto"), emptyList()), "Foto", emptyList() LanguageContainer(listOf("Foto"), listOf("Foto"), listOf("Foto"), emptyList()), "Foto", emptyList()
) )
...@@ -58,7 +68,7 @@ class IntegrationTest { ...@@ -58,7 +68,7 @@ class IntegrationTest {
val topology = val topology =
KafkaTopology(settings, TestUtilities.translationMappers, TestUtilities.elasticSearchWrapperMocked) KafkaTopology(settings, TestUtilities.translationMappers, elasticSearchWrapperMocked)
val testDriver = TopologyTestDriver(topology.build(), settings.kafkaStreamsSettings) val testDriver = TopologyTestDriver(topology.build(), settings.kafkaStreamsSettings)
val factory = ConsumerRecordFactory( val factory = ConsumerRecordFactory(
StringSerializer(), StringSerializer() StringSerializer(), StringSerializer()
......
package org.memobase package org.memobase
import io.mockk.every
import io.mockk.mockk
import java.io.File import java.io.File
import java.nio.charset.Charset import java.nio.charset.Charset
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance import org.junit.jupiter.api.TestInstance
import org.memobase.helpers.ElasticSearchWrapper
import org.memobase.helpers.JSON import org.memobase.helpers.JSON
import org.memobase.model.DocumentsSearchDoc import org.memobase.model.DocumentsSearchDoc
import org.memobase.model.FacetContainer
import org.memobase.model.LanguageContainer
import org.memobase.model.LanguageContainer.Companion
@TestInstance(TestInstance.Lifecycle.PER_CLASS) @TestInstance(TestInstance.Lifecycle.PER_CLASS)
class TestDocumentsSearchDoc { class TestDocumentsSearchDoc {
...@@ -15,8 +21,20 @@ class TestDocumentsSearchDoc { ...@@ -15,8 +21,20 @@ class TestDocumentsSearchDoc {
return File("$dataPath/$fileName").readText(Charset.defaultCharset()) return File("$dataPath/$fileName").readText(Charset.defaultCharset())
} }
private val elasticSearchWrapperMocked = run {
val internal = mockk<ElasticSearchWrapper>()
every { internal.getRecordSetName("") } returns LanguageContainer.EMPTY
internal
}
private val transformer = private val transformer =
DocumentsSearchDocBuilder(TestUtilities.translationMappers, TestUtilities.mediaUrl) DocumentsSearchDocBuilder(
TestUtilities.translationMappers,
elasticSearchWrapperMocked,
TestUtilities.mediaUrl
)
@Test @Test
fun `test minimal record required`() { fun `test minimal record required`() {
...@@ -26,9 +44,9 @@ class TestDocumentsSearchDoc { ...@@ -26,9 +44,9 @@ class TestDocumentsSearchDoc {
"TestIdentifier", "TestIdentifier",
mappedInput mappedInput
) )
assertThat(output) assertThat(output.toJson())
.isEqualTo( .isEqualTo(
DocumentsSearchDoc.DEFAULT DocumentsSearchDoc.DEFAULT.toJson()
) )
} }
} }
\ No newline at end of file
...@@ -5,6 +5,7 @@ import ch.memobase.reporting.ReportStatus ...@@ -5,6 +5,7 @@ import ch.memobase.reporting.ReportStatus
import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.registerKotlinModule import com.fasterxml.jackson.module.kotlin.registerKotlinModule
import io.mockk.every import io.mockk.every
import io.mockk.mockk
import java.io.File import java.io.File
import java.nio.charset.Charset import java.nio.charset.Charset
import org.apache.kafka.common.serialization.StringDeserializer import org.apache.kafka.common.serialization.StringDeserializer
...@@ -31,6 +32,8 @@ class TestInstitutionSearchDoc { ...@@ -31,6 +32,8 @@ class TestInstitutionSearchDoc {
return File("$dataPath/$fileName").readText(Charset.defaultCharset()) return File("$dataPath/$fileName").readText(Charset.defaultCharset())
} }
private val elasticSearchWrapperMocked = mockk<ElasticSearchWrapper>()
@Test @Test
@Disabled @Disabled
fun `test institution search doc with production es client`() { fun `test institution search doc with production es client`() {
...@@ -69,9 +72,9 @@ class TestInstitutionSearchDoc { ...@@ -69,9 +72,9 @@ class TestInstitutionSearchDoc {
fun `integration test institution`() { fun `integration test institution`() {
val settings = App.createSettings("kafkaTest1.yml") val settings = App.createSettings("kafkaTest1.yml")
every { TestUtilities.elasticSearchWrapperMocked.countNumberOfDocuments("testComplete") } returns 123 every { elasticSearchWrapperMocked.countNumberOfDocuments("testComplete") } returns 123
every { every {
TestUtilities.elasticSearchWrapperMocked.getDocumentTypesFromRecords( elasticSearchWrapperMocked.getDocumentTypesFromRecords(
"testComplete", "testComplete",
"recordSet.facet" "recordSet.facet"
) )
...@@ -81,7 +84,7 @@ class TestInstitutionSearchDoc { ...@@ -81,7 +84,7 @@ class TestInstitutionSearchDoc {
) )
) )
val topology = val topology =
KafkaTopology(settings, TestUtilities.translationMappers, TestUtilities.elasticSearchWrapperMocked) KafkaTopology(settings, TestUtilities.translationMappers, elasticSearchWrapperMocked)
val testDriver = TopologyTestDriver(topology.build(), settings.kafkaStreamsSettings) val testDriver = TopologyTestDriver(topology.build(), settings.kafkaStreamsSettings)
val factory = ConsumerRecordFactory( val factory = ConsumerRecordFactory(
StringSerializer(), StringSerializer() StringSerializer(), StringSerializer()
......
...@@ -33,6 +33,13 @@ class TestRecordSetSearchDoc { ...@@ -33,6 +33,13 @@ class TestRecordSetSearchDoc {
return File("$dataPath/$fileName").readText(Charset.defaultCharset()) return File("$dataPath/$fileName").readText(Charset.defaultCharset())
} }
private val elasticSearchWrapperMocked = run {
val internal = mockk<ElasticSearchWrapper>()
every { internal.getRecordSetName("") } returns LanguageContainer.EMPTY
internal
}
@Test @Test
fun `test create default record set `() { fun `test create default record set `() {
val searchDoc = RecordSetSearchDoc.DEFAULT val searchDoc = RecordSetSearchDoc.DEFAULT
...@@ -99,14 +106,14 @@ class TestRecordSetSearchDoc { ...@@ -99,14 +106,14 @@ class TestRecordSetSearchDoc {
fun `integration test record sets`() { fun `integration test record sets`() {
val settings = App.createSettings("kafkaTest1.yml") val settings = App.createSettings("kafkaTest1.yml")
every { TestUtilities.elasticSearchWrapperMocked.countNumberOfDocuments("") } returns 123 every { elasticSearchWrapperMocked.countNumberOfDocuments("") } returns 123
every { TestUtilities.elasticSearchWrapperMocked.getDocumentTypesFromRecords("", "") } returns listOf( every { elasticSearchWrapperMocked.getDocumentTypesFromRecords("", "") } returns listOf(
FacetContainer( FacetContainer(
LanguageContainer(listOf("Foto"), listOf("Foto"), listOf("Foto"), emptyList()), "Foto", emptyList() LanguageContainer(listOf("Foto"), listOf("Foto"), listOf("Foto"), emptyList()), "Foto", emptyList()
) )
) )
val topology = val topology =
KafkaTopology(settings, TestUtilities.translationMappers, TestUtilities.elasticSearchWrapperMocked) KafkaTopology(settings, TestUtilities.translationMappers, elasticSearchWrapperMocked)
val testDriver = TopologyTestDriver(topology.build(), settings.kafkaStreamsSettings) val testDriver = TopologyTestDriver(topology.build(), settings.kafkaStreamsSettings)
val factory = ConsumerRecordFactory( val factory = ConsumerRecordFactory(
StringSerializer(), StringSerializer() StringSerializer(), StringSerializer()
......
package org.memobase package org.memobase
import com.beust.klaxon.json import com.beust.klaxon.json
import io.mockk.every
import io.mockk.mockk
import java.io.File import java.io.File
import java.io.FileInputStream import java.io.FileInputStream
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance import org.junit.jupiter.api.TestInstance
import org.junit.jupiter.api.assertThrows import org.junit.jupiter.api.assertThrows
import org.memobase.helpers.ElasticSearchWrapper
import org.memobase.helpers.JSON import org.memobase.helpers.JSON
import org.memobase.model.LanguageContainer
@TestInstance(TestInstance.Lifecycle.PER_CLASS) @TestInstance(TestInstance.Lifecycle.PER_CLASS)
class TestTransform { class TestTransform {
private val elasticSearchWrapperMocked = run {
val internal = mockk<ElasticSearchWrapper>()
every { internal.getRecordSetName("") } returns LanguageContainer.EMPTY
internal
}
private val dataPath = "src/test/resources/data/transformer" private val dataPath = "src/test/resources/data/transformer"
private val transformer = DocumentsSearchDocBuilder(TestUtilities.translationMappers, TestUtilities.mediaUrl) private val transformer = DocumentsSearchDocBuilder(TestUtilities.translationMappers, elasticSearchWrapperMocked, TestUtilities.mediaUrl)
@Test @Test
fun `test missing record`() { fun `test missing record`() {
......
...@@ -31,7 +31,6 @@ object TestUtilities { ...@@ -31,7 +31,6 @@ object TestUtilities {
TranslationMappers(institutionTypePath, documentTypePath, accessTermPath, reuseStatementPath) TranslationMappers(institutionTypePath, documentTypePath, accessTermPath, reuseStatementPath)
val elasticSearchClient = mockk<RestHighLevelClient>() val elasticSearchClient = mockk<RestHighLevelClient>()
val elasticSearchWrapperMocked = mockk<ElasticSearchWrapper>()
fun connectToElasticSearch(host: String, port: Int, documentsIndex: String): RestHighLevelClient { fun connectToElasticSearch(host: String, port: Int, documentsIndex: String): RestHighLevelClient {
......
{"title":[{"de":[],"fr":[],"it":[],"un":["Diaserie zum Thema Säuglingspflege; \"Ablesen des Thermometers.\" - Krankenschwester am Fieber messen bei einem Säugling; Deutsches Hygiene-Museum, Dresden; um 1930"]}],"type":{"name":{"de":["Fotografie"],"fr":["Photographie"],"it":["Fotografia"],"un":[]},"filter":"Foto"},"sourceID":"Sozarch_F_5146-Gb-40-042","oldMemobaseId":"SozArch-Sozarch_F_5146-Gb-40-042","rightsHolder":[{"de":[],"fr":[],"it":[],"un":["Schweizerisches Sozialarchiv"]}],"sameAs":["http://www.bild-video-ton.ch/bestand/objekt/Sozarch_F_5146-Gb-40-042"],"format":[{"displayLabel":{"de":[],"fr":[],"it":[],"un":["Glaspositiv"]},"name":{"de":["Fotoplatte"],"fr":["plaque photographique"],"it":["lastra fotografica"],"un":[]}}],"language":[{"displayLabel":{"de":[],"fr":[],"it":[],"un":["ger"]},"name":{"de":["Deutsch"],"fr":["allemand"],"it":["tedesco"],"un":[]},"type":"content"}],"keywords":{"de":[],"fr":[],"it":[],"un":["soziale Fragen","Altersgliederung","Bevölkerung","Bevölkerungsaufbau","frühe Kindheit; soziale Fragen","Gesundheit","Gesundheitsförderung","Gesundheitspolitik"]},"personsFacet":{},"agentCreator":[{"name":{"de":[],"fr":[],"it":[],"un":["Unbekannt"]},"relation":{"de":[],"fr":[],"it":[],"un":["Author"]}}],"placeFacet":{},"temporal":[{"date":"1921-1930 / 1931-1940"}],"dateCreated":[{"date":"um 1930"}],"institution":[{"name":{"de":[],"fr":[],"it":[],"un":[]},"facet":["soz"]}],"recordSet":{"name":{"de":[],"fr":[],"it":[],"un":[]},"facet":["soz-004"]},"memoriavClaim":true,"locator":"https://media.memobase.k8s.unibas.ch/memo/soz-004-Sozarch_F_5146-Gb-40-042-1","mediaLocation":"local","accessDigital":[{"name":{"de":["Online"],"fr":["En ligne"],"it":["Online"],"un":[]},"filter":"public"}],"usageDigital":["http://rightsstatements.org/vocab/CNE/1.0/"],"usageDigitalGroup":[{"name":{"de":["Unklar (Copyright nicht bekannt)"],"fr":[""],"it":[""],"un":[]},"filter":"http://rightsstatements.org/vocab/CNE/1.0/"}],"digital":{},"callNumber":["Sozarch_F_5146-Gb-40-042"],"accessPhysical":[{"name":{"de":["vor Ort"],"fr":["Sur place"],"it":["Nel local"],"un":[]},"filter":"onsite"}],"usagePhysical":["http://rightsstatements.org/vocab/CNE/1.0/"],"colourPhysical":[{"de":[],"fr":[],"it":[],"un":["s-w"]}],"access":[{"name":{"de":["Online"],"fr":["En ligne"],"it":["Online"],"un":[]},"filter":"public"},{"name":{"de":["vor Ort"],"fr":["Sur place"],"it":["Nel local"],"un":[]},"filter":"onsite"}],"published":false,"suggest":{"title":["Diaserie zum Thema Säuglingspflege; \"Ablesen des Thermometers.\" - Krankenschwester am Fieber messen bei einem Säugling; Deutsches Hygiene-Museum, Dresden; um 1930"],"keywords":["soziale Fragen","Altersgliederung","Bevölkerung","Bevölkerungsaufbau","Gesundheit","frühe Kindheit; soziale Fragen","Gesundheitsförderung","Gesundheitspolitik"]},"id":"fad-001-DON3196"} {"title":[{"de":[],"fr":[],"it":[],"un":["Diaserie zum Thema Säuglingspflege; \"Ablesen des Thermometers.\" - Krankenschwester am Fieber messen bei einem Säugling; Deutsches Hygiene-Museum, Dresden; um 1930"]}],"type":{"name":{"de":["Fotografie"],"fr":["Photographie"],"it":["Fotografia"],"un":[]},"filter":"Foto"},"sourceID":"Sozarch_F_5146-Gb-40-042","oldMemobaseId":"SozArch-Sozarch_F_5146-Gb-40-042","rightsHolder":[{"de":[],"fr":[],"it":[],"un":["Schweizerisches Sozialarchiv"]}],"sameAs":["http://www.bild-video-ton.ch/bestand/objekt/Sozarch_F_5146-Gb-40-042"],"format":[{"displayLabel":{"de":[],"fr":[],"it":[],"un":["Glaspositiv"]},"name":{"de":["Fotoplatte"],"fr":["plaque photographique"],"it":["lastra fotografica"],"un":[]}}],"language":[{"displayLabel":{"de":[],"fr":[],"it":[],"un":["ger"]},"name":{"de":["Deutsch"],"fr":["allemand"],"it":["tedesco"],"un":[]},"type":"content"}],"keywords":{"de":[],"fr":[],"it":[],"un":["soziale Fragen","Altersgliederung","Bevölkerung","Bevölkerungsaufbau","frühe Kindheit; soziale Fragen","Gesundheit","Gesundheitsförderung","Gesundheitspolitik"]},"personsFacet":{},"agentCreator":[{"name":{"de":[],"fr":[],"it":[],"un":["Unbekannt"]},"relation":{"de":[],"fr":[],"it":[],"un":["Author"]}}],"placeFacet":{},"temporal":[{"date":"1921-1930 / 1931-1940"}],"dateCreated":[{"date":"um 1930"}],"institution":[{"name":{"de":["soz"],"fr":["soz"],"it":["soz"],"un":["soz"]},"filter":"soz","facet":["soz"]}],"recordSet":{"name":{"de":["soz-004"],"fr":["soz-004"],"it":["soz-004"],"un":["soz-004"]},"facet":["soz-004"]},"memoriavClaim":true,"locator":"https://media.memobase.k8s.unibas.ch/memo/soz-004-Sozarch_F_5146-Gb-40-042-1","mediaLocation":"local","accessDigital":[{"name":{"de":["Online"],"fr":["En ligne"],"it":["Online"],"un":[]},"filter":"public"}],"usageDigital":["http://rightsstatements.org/vocab/CNE/1.0/"],"usageDigitalGroup":[{"name":{"de":["Unklar (Copyright nicht bekannt)"],"fr":[""],"it":[""],"un":[]},"filter":"http://rightsstatements.org/vocab/CNE/1.0/"}],"digital":{},"callNumber":["Sozarch_F_5146-Gb-40-042"],"accessPhysical":[{"name":{"de":["vor Ort"],"fr":["Sur place"],"it":["Nel local"],"un":[]},"filter":"onsite"}],"usagePhysical":["http://rightsstatements.org/vocab/CNE/1.0/"],"colourPhysical":[{"de":[],"fr":[],"it":[],"un":["s-w"]}],"access":[{"name":{"de":["Online"],"fr":["En ligne"],"it":["Online"],"un":[]},"filter":"public"},{"name":{"de":["vor Ort"],"fr":["Sur place"],"it":["Nel local"],"un":[]},"filter":"onsite"}],"published":false,"suggest":{"title":["Diaserie zum Thema Säuglingspflege; \"Ablesen des Thermometers.\" - Krankenschwester am Fieber messen bei einem Säugling; Deutsches Hygiene-Museum, Dresden; um 1930"],"keywords":["soziale Fragen","Altersgliederung","Bevölkerung","Bevölkerungsaufbau","Gesundheit","frühe Kindheit; soziale Fragen","Gesundheitsförderung","Gesundheitspolitik"]},"id":"fad-001-DON3196"}
\ No newline at end of file \ No newline at end of file
{"title":[{"de":[],"fr":[],"it":[],"un":["\"Auf der Alp Gitschenen - Projektleiter, Gemeindebehörden, Journalisten, Pro Juventute Mitarbeiter\"; 07.08.1974"]}],"type":{"name":{"de":["Fotografie"],"fr":["Photographie"],"it":["Fotografia"],"un":[]},"filter":"Foto"},"sourceID":"Sozarch_F_5146-Fc-0253","oldMemobaseId":"SozArch-Sozarch_F_5146-Fc-0253","rightsHolder":[{"de":[],"fr":[],"it":[],"un":["Schweizerisches Sozialarchiv"]}],"sameAs":["http://www.bild-video-ton.ch/bestand/objekt/Sozarch_F_5146-Fc-0253"],"format":[{"displayLabel":{"de":[],"fr":[],"it":[],"un":["Papierabzug"]},"name":{"de":["Abzug"],"fr":["épreuve photographique"],"it":["GALATEO MANCANTE"],"un":[]}}],"keywords":{"de":[],"fr":[],"it":[],"un":[]},"personsFacet":{},"agentCreator":[{"name":{"de":[],"fr":[],"it":[],"un":["Perrottet, Julia"]},"relation":{"de":[],"fr":[],"it":[],"un":["Author"]}}],"placeRelated":[{"name":{"de":[],"fr":[],"it":[],"un":["Schweiz, Uri, Isenthal"]},"filter":"Schweiz, Uri, Isenthal","facet":["0~S~","1~S~Schweiz, Uri, Isenthal~"]}],"placeFacet":{"facet":["0~S~","1~S~Schweiz, Uri, Isenthal~"],"filter":["Schweiz, Uri, Isenthal"]},"institution":[{"name":{"de":[],"fr":[],"it":[],"un":[]},"facet":["soz"]}],"recordSet":{"name":{"de":[],"fr":[],"it":[],"un":[]},"facet":["soz-004"]},"memoriavClaim":true,"locator":"https://media.memobase.k8s.unibas.ch/memo/soz-004-Sozarch_F_5146-Fc-0253-1","mediaLocation":"remote","accessDigital":[{"name":{"de":["Online"],"fr":["En ligne"],"it":["Online"],"un":[]},"filter":"public"}],"usageDigital":["http://rightsstatements.org/vocab/CNE/1.0/"],"usageDigitalGroup":[{"name":{"de":["Unklar (Copyright nicht bekannt)"],"fr":[""],"it":[""],"un":[]},"filter":"http://rightsstatements.org/vocab/CNE/1.0/"}],"digital":{},"callNumber":["Sozarch_F_5146-Fc-0253"],"accessPhysical":[{"name":{"de":["vor Ort"],"fr":["Sur place"],"it":["Nel local"],"un":[]},"filter":"onsite"}],"usagePhysical":["http://rightsstatements.org/vocab/CNE/1.0/"],"colourPhysical":[{"de":[],"fr":[],"it":[],"un":["s-w"]}],"access":[{"name":{"de":["Online"],"fr":["En ligne"],"it":["Online"],"un":[]},"filter":"public"},{"name":{"de":["vor Ort"],"fr":["Sur place"],"it":["Nel local"],"un":[]},"filter":"onsite"}],"published":false,"suggest":{"title":["\"Auf der Alp Gitschenen - Projektleiter, Gemeindebehörden, Journalisten, Pro Juventute Mitarbeiter\"; 07.08.1974"]},"id":"Burgerbib-Krebser-208576"} {"title":[{"de":[],"fr":[],"it":[],"un":["\"Auf der Alp Gitschenen - Projektleiter, Gemeindebehörden, Journalisten, Pro Juventute Mitarbeiter\"; 07.08.1974"]}],"type":{"name":{"de":["Fotografie"],"fr":["Photographie"],"it":["Fotografia"],"un":[]},"filter":"Foto"},"sourceID":"Sozarch_F_5146-Fc-0253","oldMemobaseId":"SozArch-Sozarch_F_5146-Fc-0253","rightsHolder":[{"de":[],"fr":[],"it":[],"un":["Schweizerisches Sozialarchiv"]}],"sameAs":["http://www.bild-video-ton.ch/bestand/objekt/Sozarch_F_5146-Fc-0253"],"format":[{"displayLabel":{"de":[],"fr":[],"it":[],"un":["Papierabzug"]},"name":{"de":["Abzug"],"fr":["épreuve photographique"],"it":["GALATEO MANCANTE"],"un":[]}}],"keywords":{"de":[],"fr":[],"it":[],"un":[]},"personsFacet":{},"agentCreator":[{"name":{"de":[],"fr":[],"it":[],"un":["Perrottet, Julia"]},"relation":{"de":[],"fr":[],"it":[],"un":["Author"]}}],"placeRelated":[{"name":{"de":[],"fr":[],"it":[],"un":["Schweiz, Uri, Isenthal"]},"filter":"Schweiz, Uri, Isenthal","facet":["0~S~","1~S~Schweiz, Uri, Isenthal~"]}],"placeFacet":{"facet":["0~S~","1~S~Schweiz, Uri, Isenthal~"],"filter":["Schweiz, Uri, Isenthal"]},"institution":[{"name":{"de":["soz"],"fr":["soz"],"it":["soz"],"un":["soz"]},"filter":"soz","facet":["soz"]}],"recordSet":{"name":{"de":["soz-004"],"fr":["soz-004"],"it":["soz-004"],"un":["soz-004"]},"facet":["soz-004"]},"memoriavClaim":true,"locator":"https://media.memobase.k8s.unibas.ch/memo/soz-004-Sozarch_F_5146-Fc-0253-1","mediaLocation":"remote","accessDigital":[{"name":{"de":["Online"],"fr":["En ligne"],"it":["Online"],"un":[]},"filter":"public"}],"usageDigital":["http://rightsstatements.org/vocab/CNE/1.0/"],"usageDigitalGroup":[{"name":{"de":["Unklar (Copyright nicht bekannt)"],"fr":[""],"it":[""],"un":[]},"filter":"http://rightsstatements.org/vocab/CNE/1.0/"}],"digital":{},"callNumber":["Sozarch_F_5146-Fc-0253"],"accessPhysical":[{"name":{"de":["vor Ort"],"fr":["Sur place"],"it":["Nel local"],"un":[]},"filter":"onsite"}],"usagePhysical":["http://rightsstatements.org/vocab/CNE/1.0/"],"colourPhysical":[{"de":[],"fr":[],"it":[],"un":["s-w"]}],"access":[{"name":{"de":["Online"],"fr":["En ligne"],"it":["Online"],"un":[]},"filter":"public"},{"name":{"de":["vor Ort"],"fr":["Sur place"],"it":["Nel local"],"un":[]},"filter":"onsite"}],"published":false,"suggest":{"title":["\"Auf der Alp Gitschenen - Projektleiter, Gemeindebehörden, Journalisten, Pro Juventute Mitarbeiter\"; 07.08.1974"]},"id":"Burgerbib-Krebser-208576"}
\ No newline at end of file \ No newline at end of file