Commit dc714882 authored by Jonas Waeber's avatar Jonas Waeber
Browse files

Add suggest fields

parent b7b08fc0
Pipeline #13245 passed with stages
in 6 minutes and 5 seconds
...@@ -25,12 +25,31 @@ object KEYS { ...@@ -25,12 +25,31 @@ object KEYS {
const val firstName = "firstName" const val firstName = "firstName"
const val lastName = "lastName" const val lastName = "lastName"
const val name = "name" const val name = "name"
const val title = "title"
const val prefLabel = "prefLabel"
const val agentIsTargetOfCreationRelation = "agentIsTargetOfCreationRelation" const val agentIsTargetOfCreationRelation = "agentIsTargetOfCreationRelation"
const val hasSubject = "hasSubject"
const val placeOfCapture = "P60556"
const val spatial = "spatial"
const val producer = "P60441"
const val publishedBy = "publishedBy"
const val contributor = "contributor" const val contributor = "contributor"
const val creator = "creator" const val creator = "creator"
const val Person = "Person" const val Person = "Person"
const val Instantiation = "Instantiation"
const val Place = "Place" const val Place = "Place"
const val Title = "Title"
const val Instantiation = "Instantiation"
const val Record = "Record"
const val Concept = "Concept"
object TitleTypes {
const val main = "main"
const val series = "series"
const val broadcast = "broadcast"
}
} }
...@@ -25,6 +25,7 @@ import org.memobase.builders.IFieldBuilder ...@@ -25,6 +25,7 @@ import org.memobase.builders.IFieldBuilder
import org.memobase.builders.PersonContainerBuilder import org.memobase.builders.PersonContainerBuilder
import org.memobase.builders.PersonFacetBuilder import org.memobase.builders.PersonFacetBuilder
import org.memobase.builders.PlaceFacetBuilder import org.memobase.builders.PlaceFacetBuilder
import org.memobase.builders.SuggestContainerBuilder
import org.memobase.helpers.CarrierType import org.memobase.helpers.CarrierType
import org.memobase.helpers.Extract import org.memobase.helpers.Extract
import org.memobase.helpers.FacetBuildHelpers import org.memobase.helpers.FacetBuildHelpers
...@@ -45,18 +46,27 @@ class SearchDocTransform { ...@@ -45,18 +46,27 @@ class SearchDocTransform {
val physicalObject = val physicalObject =
input.values.firstOrNull { it["@type"] == NS.rico + "Instantiation" && it["type"] == "physicalObject" } input.values.firstOrNull { it["@type"] == NS.rico + "Instantiation" && it["type"] == "physicalObject" }
val hasSubjectIds = Extract.identifiers(record[KEYS.hasSubject])
val publishedByIds = Extract.identifiers(record[KEYS.publishedBy])
val producerIds = Extract.identifiers(record[KEYS.producer])
val spatialIds = Extract.identifiers(record[KEYS.spatial])
val placeOfCaptureIds = Extract.identifiers(record[KEYS.placeOfCapture])
val personFacetBuilder = PersonFacetBuilder() val personFacetBuilder = PersonFacetBuilder()
val subjectPersonBuilder = PersonContainerBuilder("hasSubject", record, null, input) val subjectPersonBuilder = PersonContainerBuilder(hasSubjectIds, null, input)
val publisherPersonBuilder = PersonContainerBuilder("publishedBy", record, null, input) val publisherPersonBuilder = PersonContainerBuilder(publishedByIds, null, input)
val producersPersonBuilder = PersonContainerBuilder("P60441", record, null, input) val producersPersonBuilder = PersonContainerBuilder(producerIds, null, input)
val contributorPersonBuilder = PersonContainerBuilder("", record, KEYS.contributor, input) val contributorPersonBuilder = PersonContainerBuilder(emptyList(), KEYS.contributor, input)
val creatorPersonBuilder = PersonContainerBuilder("", record, KEYS.creator, input) val creatorPersonBuilder = PersonContainerBuilder(emptyList(), KEYS.creator, input)
val placesRelatedBuilder = FacettedContainerBuilder("spatial", record, KEYS.Place, KEYS.name, FacetBuildHelpers::place) val placesRelatedBuilder = FacettedContainerBuilder(spatialIds, KEYS.Place, KEYS.name, FacetBuildHelpers::place)
val placeCapturedBuilder = FacettedContainerBuilder("P60556", record, KEYS.Place, KEYS.name, FacetBuildHelpers::place) val placeCapturedBuilder =
FacettedContainerBuilder(placeOfCaptureIds, KEYS.Place, KEYS.name, FacetBuildHelpers::place)
val placeFacetBuilder = PlaceFacetBuilder() val placeFacetBuilder = PlaceFacetBuilder()
val suggestContainerBuilder = SuggestContainerBuilder(hasSubjectIds)
for (item in input.values) { for (item in input.values) {
for (builder: IFieldBuilder in listOf( for (builder: IFieldBuilder in listOf(
personFacetBuilder, personFacetBuilder,
...@@ -67,7 +77,8 @@ class SearchDocTransform { ...@@ -67,7 +77,8 @@ class SearchDocTransform {
creatorPersonBuilder, creatorPersonBuilder,
placeFacetBuilder, placeFacetBuilder,
placeCapturedBuilder, placeCapturedBuilder,
placesRelatedBuilder placesRelatedBuilder,
suggestContainerBuilder
)) { )) {
if (builder.filter(item)) { if (builder.filter(item)) {
builder.append(item) builder.append(item)
...@@ -221,7 +232,8 @@ class SearchDocTransform { ...@@ -221,7 +232,8 @@ class SearchDocTransform {
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() },
format = format format = format,
suggest = suggestContainerBuilder.build()[0]
) )
} }
} }
...@@ -18,16 +18,17 @@ ...@@ -18,16 +18,17 @@
package org.memobase.builders package org.memobase.builders
import com.beust.klaxon.JsonArray
import com.beust.klaxon.JsonObject import com.beust.klaxon.JsonObject
import org.memobase.KEYS import org.memobase.KEYS
import org.memobase.helpers.Extract import org.memobase.helpers.Extract
import org.memobase.model.FacettedContainer import org.memobase.model.FacettedContainer
import org.memobase.rdf.NS import org.memobase.rdf.NS
/**
* @param identifiers: A list of identifiers to filter on.
*/
class FacettedContainerBuilder( class FacettedContainerBuilder(
private val sourceProperty: String, private val identifiers: List<String>,
private val sourceResource: JsonObject,
private val targetType: String, private val targetType: String,
private val nameProperty: String, private val nameProperty: String,
private val facetFunction: (jsonObject: JsonObject) -> List<String> private val facetFunction: (jsonObject: JsonObject) -> List<String>
...@@ -37,22 +38,7 @@ class FacettedContainerBuilder( ...@@ -37,22 +38,7 @@ class FacettedContainerBuilder(
override fun filter(jsonObject: JsonObject): Boolean { override fun filter(jsonObject: JsonObject): Boolean {
if (jsonObject[KEYS.atType] != NS.rico + targetType) return false if (jsonObject[KEYS.atType] != NS.rico + targetType) return false
return sourceResource[sourceProperty].let { return identifiers.contains(jsonObject[KEYS.entityId])
when (it) {
is String -> it == jsonObject[KEYS.entityId] as String
is JsonObject -> it[KEYS.entityId] as String == jsonObject[KEYS.entityId] as String
is JsonArray<*> -> {
it.any { child ->
when (child) {
is String -> child == jsonObject[KEYS.entityId] as String
is JsonObject -> child[KEYS.entityId] as String == jsonObject[KEYS.entityId] as String
else -> false
}
}
}
else -> false
}
}
} }
override fun append(jsonObject: JsonObject): String { override fun append(jsonObject: JsonObject): String {
......
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
package org.memobase.builders package org.memobase.builders
import com.beust.klaxon.JsonArray
import com.beust.klaxon.JsonObject import com.beust.klaxon.JsonObject
import org.memobase.KEYS import org.memobase.KEYS
import org.memobase.helpers.Extract import org.memobase.helpers.Extract
...@@ -27,8 +26,7 @@ import org.memobase.model.PersonContainer ...@@ -27,8 +26,7 @@ import org.memobase.model.PersonContainer
import org.memobase.rdf.NS import org.memobase.rdf.NS
class PersonContainerBuilder( class PersonContainerBuilder(
private val sourceProperty: String, private val identifiers: List<String>,
private val sourceResource: JsonObject,
private val creationRelationType: String?, private val creationRelationType: String?,
private val inputMap: Map<String, JsonObject> private val inputMap: Map<String, JsonObject>
) : ) :
...@@ -48,22 +46,7 @@ class PersonContainerBuilder( ...@@ -48,22 +46,7 @@ class PersonContainerBuilder(
false false
} }
} else { } else {
sourceResource[sourceProperty].let { identifiers.contains(jsonObject[KEYS.entityId])
when (it) {
is String -> it == jsonObject[KEYS.entityId] as String
is JsonObject -> it[KEYS.entityId] as String == jsonObject[KEYS.entityId] as String
is JsonArray<*> -> {
it.any { child ->
when (child) {
is String -> child == jsonObject[KEYS.entityId] as String
is JsonObject -> child[KEYS.entityId] as String == jsonObject[KEYS.entityId] as String
else -> false
}
}
}
else -> false
}
}
} }
} }
......
/*
* search-doc-service
* Copyright (C) 2020 Memoriav
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.memobase.builders
import com.beust.klaxon.JsonObject
import org.memobase.KEYS
import org.memobase.helpers.Extract
import org.memobase.model.SuggestContainer
import org.memobase.rdf.NS
class SuggestContainerBuilder(private val hasSubjectIds: List<String>) : IFieldBuilder {
private val titles = mutableListOf<String>()
private val seriesTitles = mutableListOf<String>()
private val broadcastTitles = mutableListOf<String>()
private val keywords = mutableListOf<String>()
override fun filter(jsonObject: JsonObject): Boolean {
return when {
jsonObject[KEYS.atType] == NS.skos + KEYS.Concept -> {
hasSubjectIds.contains(jsonObject[KEYS.entityId])
}
jsonObject[KEYS.atType] == NS.rico + KEYS.Title -> true
else -> false
}
}
override fun append(jsonObject: JsonObject): String {
return when (jsonObject[KEYS.atType]) {
NS.skos + KEYS.Concept -> parseKeywords(jsonObject)
NS.rico + KEYS.Title -> parseTitles(jsonObject)
else -> ""
}
}
private fun parseTitles(jsonObject: JsonObject): String {
return when (jsonObject[KEYS.ricoType]) {
KEYS.TitleTypes.main -> {
titles.addAll(
Extract.languageContainer("main-title", jsonObject[KEYS.title])
.reduce { acc, languageContainer -> acc.merge(languageContainer) }.toList()
)
""
}
KEYS.TitleTypes.series -> {
seriesTitles.addAll(
Extract.languageContainer("series-title", jsonObject[KEYS.title])
.reduce { acc, languageContainer -> acc.merge(languageContainer) }.toList()
)
""
}
KEYS.TitleTypes.broadcast -> {
broadcastTitles.addAll(
Extract.languageContainer("broadcast-title", jsonObject[KEYS.title])
.reduce { acc, languageContainer -> acc.merge(languageContainer) }.toList()
)
""
}
else -> "Unknown title type ${jsonObject[KEYS.ricoType]}."
}
}
private fun parseKeywords(jsonObject: JsonObject): String {
keywords.addAll(
Extract.languageContainer("keywords-concept", jsonObject[KEYS.prefLabel])
.reduce { acc, languageContainer -> acc.merge(languageContainer) }.toList()
)
return ""
}
override fun build(): List<SuggestContainer> {
return listOf(
SuggestContainer(
title = titles,
seriesTitle = seriesTitles,
broadcastTitle = broadcastTitles,
keywords = keywords
)
)
}
}
...@@ -134,12 +134,6 @@ object Extract { ...@@ -134,12 +134,6 @@ object Extract {
} }
} }
fun extractPlaces(entities: List<JsonObject>): List<LanguageContainer> {
return entities.flatMap {
languageContainer(it["@id"] as String, it["name"])
}
}
fun extractSourceId(entities: List<JsonObject>): String { fun extractSourceId(entities: List<JsonObject>): String {
return entities.first { return entities.first {
it["type"] as String == "original" it["type"] as String == "original"
...@@ -188,7 +182,7 @@ object Extract { ...@@ -188,7 +182,7 @@ object Extract {
} }
} }
fun identifier(value: Any?): List<String> { fun identifiers(value: Any?): List<String> {
return when (value) { return when (value) {
is String -> listOf(value) is String -> listOf(value)
is JsonObject -> value["@id"].let { if (it is String) listOf(it) else emptyList() } is JsonObject -> value["@id"].let { if (it is String) listOf(it) else emptyList() }
......
...@@ -103,5 +103,8 @@ data class SearchDoc( ...@@ -103,5 +103,8 @@ data class SearchDoc(
val format: List<FacettedContainer>, val format: List<FacettedContainer>,
// Combined // Combined
val access: List<String> val access: List<String>,
// auto complete source
val suggest: SuggestContainer
) )
/*
* search-doc-service
* Copyright (C) 2020 Memoriav
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.memobase.model
data class SuggestContainer(
val title: List<String>,
val seriesTitle: List<String>,
val broadcastTitle: List<String>,
val keywords: List<String>
)
{"title":[{"de":[],"fr":[],"it":[],"un":["Bern: Altstadt, obere; Bundesplatz 4; Bärenplatz (31); Käfiggässchen; -- Fuhrwerk; Automobil; Lastwagen; Transport, Verkehr; Strassenbeleuchtung"]}],"type":"Foto","sourceID":"216133","id":"https://memobase.ch/record/Burgerbib-Krebser-216133","descriptiveNote":[{"de":[],"fr":[],"it":[],"un":["Datierung: Bundesplatz / Büren-Besitzung<br>"]}],"rightsHolder":[{"de":[],"fr":[],"it":[],"un":["Burgerbibliothek Bern"]}],"sameAs":["http://katalog.burgerbib.ch/detail.aspx?ID=216133"],"keywords":[{"name":{"de":[],"fr":[],"it":[],"un":["Transport, Verkehr"]},"facet":["Transport, Verkehr"]}],"personCreator":[{"name":{"de":[],"fr":[],"it":[],"un":["Anonym"]},"relation":{"de":[],"fr":[],"it":[],"un":["author"]},"facet":["0~A~#","1~A~Anonym~#"]}],"personContributor":[{"name":{"de":[],"fr":[],"it":[],"un":["Familie Krebser"]},"relation":{"de":[],"fr":[],"it":[],"un":["Collector/Sammler"]},"facet":["0~F~#","1~F~Familie Krebser~#"]}],"personsFacet":["0~A~#","1~A~Anonym~#","0~F~#","1~F~Familie Krebser~#"],"placeRelated":[{"name":{"de":[],"fr":[],"it":[],"un":["Käfiggässchen"]},"facet":["0~K~#","1~K~Käfiggässchen~#"]}],"placeFacet":["0~K~#","1~K~Käfiggässchen~#"],"dateCreated":[{"date":"1900/1909","facet":[]}],"institution":[{"name":{"de":[],"fr":[],"it":[],"un":[]},"facet":["https://memobase.ch/institution/Burgerbib"]}],"recordSet":{"name":{"de":[],"fr":[],"it":[],"un":[]},"facet":["https://memobase.ch/recordSet/Burgerbib-Krebser"]},"memoriavClaim":true,"callNumber":["Historische Sammlung Krebser 13/2"],"physicalCharacteristics":[{"de":[],"fr":[],"it":[],"un":["Weite: 85 mm","Höhe: 100 mm"]}],"format":[{"name":{"de":["Glasplatte"],"fr":[],"it":[],"un":[]},"facet":["http://www.wikidata.org/entity/Q1138868"]},{"name":{"de":[],"fr":[],"it":[],"un":["Glasplatte"]},"facet":[]}]} {"title":[{"de":[],"fr":[],"it":[],"un":["Bern: Altstadt, obere; Bundesplatz 4; Bärenplatz (31); Käfiggässchen; -- Fuhrwerk; Automobil; Lastwagen; Transport, Verkehr; Strassenbeleuchtung"]}],"type":"Foto","sourceID":"216133","id":"https://memobase.ch/record/Burgerbib-Krebser-216133","descriptiveNote":[{"de":[],"fr":[],"it":[],"un":["Datierung: Bundesplatz / Büren-Besitzung<br>"]}],"rightsHolder":[{"de":[],"fr":[],"it":[],"un":["Burgerbibliothek Bern"]}],"sameAs":["http://katalog.burgerbib.ch/detail.aspx?ID=216133"],"keywords":[{"name":{"de":[],"fr":[],"it":[],"un":["Transport, Verkehr"]},"facet":["Transport, Verkehr"]}],"personCreator":[{"name":{"de":[],"fr":[],"it":[],"un":["Anonym"]},"relation":{"de":[],"fr":[],"it":[],"un":["author"]},"facet":["0~A~#","1~A~Anonym~#"]}],"personContributor":[{"name":{"de":[],"fr":[],"it":[],"un":["Familie Krebser"]},"relation":{"de":[],"fr":[],"it":[],"un":["Collector/Sammler"]},"facet":["0~F~#","1~F~Familie Krebser~#"]}],"personsFacet":["0~A~#","1~A~Anonym~#","0~F~#","1~F~Familie Krebser~#"],"placeRelated":[{"name":{"de":[],"fr":[],"it":[],"un":["Käfiggässchen"]},"facet":["0~K~#","1~K~Käfiggässchen~#"]}],"placeFacet":["0~K~#","1~K~Käfiggässchen~#"],"dateCreated":[{"date":"1900/1909","facet":[]}],"institution":[{"name":{"de":[],"fr":[],"it":[],"un":[]},"facet":["https://memobase.ch/institution/Burgerbib"]}],"recordSet":{"name":{"de":[],"fr":[],"it":[],"un":[]},"facet":["https://memobase.ch/recordSet/Burgerbib-Krebser"]},"memoriavClaim":true,"callNumber":["Historische Sammlung Krebser 13/2"],"physicalCharacteristics":[{"de":[],"fr":[],"it":[],"un":["Weite: 85 mm","Höhe: 100 mm"]}],"format":[{"name":{"de":["Glasplatte"],"fr":[],"it":[],"un":[]},"facet":["http://www.wikidata.org/entity/Q1138868"]},{"name":{"de":[],"fr":[],"it":[],"un":["Glasplatte"]},"facet":[]}],"suggest":{"title":["Bern: Altstadt, obere; Bundesplatz 4; Bärenplatz (31); Käfiggässchen; -- Fuhrwerk; Automobil; Lastwagen; Transport, Verkehr; Strassenbeleuchtung"],"seriesTitle":[],"broadcastTitle":[],"keywords":["Transport, Verkehr"]}}
\ No newline at end of file \ No newline at end of file
{"title":[{"de":[],"fr":[],"it":[],"un":["Anonym -- Armut"]}],"type":"Foto","sourceID":"208576","id":"https://memobase.ch/record/Burgerbib-Krebser-208576","abstract":[{"de":[],"fr":[],"it":[],"un":["Bildeintrag: auf der Verpackung: 49543<br>"]}],"descriptiveNote":[{"de":[],"fr":[],"it":[],"un":["Datierung: Negativnummer<br>"]}],"rightsHolder":[{"de":[],"fr":[],"it":[],"un":["Burgerbibliothek Bern"]}],"sameAs":["http://katalog.burgerbib.ch/detail.aspx?ID=208576"],"keywords":[{"name":{"de":[],"fr":[],"it":[],"un":["Armut"]},"facet":["Armut"]}],"personCreator":[{"name":{"de":[],"fr":[],"it":[],"un":["Moeglé, Jean"]},"relation":{"de":[],"fr":[],"it":[],"un":["author"]},"facet":["0~M~#","1~M~Moeglé, Jean~#"]}],"personContributor":[{"name":{"de":[],"fr":[],"it":[],"un":["Familie Krebser"]},"relation":{"de":[],"fr":[],"it":[],"un":["Collector/Sammler"]},"facet":["0~F~#","1~F~Familie Krebser~#"]}],"personsFacet":["0~F~#","1~F~Familie Krebser~#","0~M~#","1~M~Moeglé, Jean~#"],"dateCreated":[{"date":"20. Jh.","facet":[]}],"institution":[{"name":{"de":[],"fr":[],"it":[],"un":[]},"facet":["https://memobase.ch/institution/Burgerbib"]}],"recordSet":{"name":{"de":[],"fr":[],"it":[],"un":[]},"facet":["https://memobase.ch/recordSet/Burgerbib-Krebser"]},"memoriavClaim":true,"callNumber":["Historische Sammlung Krebser 64/21"],"physicalCharacteristics":[{"de":[],"fr":[],"it":[],"un":["Weite: 165 mm","Höhe: 120 mm"]}],"format":[{"name":{"de":["Glasplatte"],"fr":[],"it":[],"un":[]},"facet":["http://www.wikidata.org/entity/Q1138868"]},{"name":{"de":[],"fr":[],"it":[],"un":["Glasplatte"]},"facet":[]}]} {"title":[{"de":[],"fr":[],"it":[],"un":["Anonym -- Armut"]}],"type":"Foto","sourceID":"208576","id":"https://memobase.ch/record/Burgerbib-Krebser-208576","abstract":[{"de":[],"fr":[],"it":[],"un":["Bildeintrag: auf der Verpackung: 49543<br>"]}],"descriptiveNote":[{"de":[],"fr":[],"it":[],"un":["Datierung: Negativnummer<br>"]}],"rightsHolder":[{"de":[],"fr":[],"it":[],"un":["Burgerbibliothek Bern"]}],"sameAs":["http://katalog.burgerbib.ch/detail.aspx?ID=208576"],"keywords":[{"name":{"de":[],"fr":[],"it":[],"un":["Armut"]},"facet":["Armut"]}],"personCreator":[{"name":{"de":[],"fr":[],"it":[],"un":["Moeglé, Jean"]},"relation":{"de":[],"fr":[],"it":[],"un":["author"]},"facet":["0~M~#","1~M~Moeglé, Jean~#"]}],"personContributor":[{"name":{"de":[],"fr":[],"it":[],"un":["Familie Krebser"]},"relation":{"de":[],"fr":[],"it":[],"un":["Collector/Sammler"]},"facet":["0~F~#","1~F~Familie Krebser~#"]}],"personsFacet":["0~F~#","1~F~Familie Krebser~#","0~M~#","1~M~Moeglé, Jean~#"],"dateCreated":[{"date":"20. Jh.","facet":[]}],"institution":[{"name":{"de":[],"fr":[],"it":[],"un":[]},"facet":["https://memobase.ch/institution/Burgerbib"]}],"recordSet":{"name":{"de":[],"fr":[],"it":[],"un":[]},"facet":["https://memobase.ch/recordSet/Burgerbib-Krebser"]},"memoriavClaim":true,"callNumber":["Historische Sammlung Krebser 64/21"],"physicalCharacteristics":[{"de":[],"fr":[],"it":[],"un":["Weite: 165 mm","Höhe: 120 mm"]}],"format":[{"name":{"de":["Glasplatte"],"fr":[],"it":[],"un":[]},"facet":["http://www.wikidata.org/entity/Q1138868"]},{"name":{"de":[],"fr":[],"it":[],"un":["Glasplatte"]},"facet":[]}],"suggest":{"title":["Anonym -- Armut"],"seriesTitle":[],"broadcastTitle":[],"keywords":["Armut"]}}
\ No newline at end of file \ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment