-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Duplicated resources in Gravsearch result #1588
Comments
Should not be possible, can you make a small test case that we can reproduce? |
Maybe a bug in |
The issue probably comes from the We have some sparql logs to provide to you, first, the gravsearch: PREFIX knora-api: <http://api.knora.org/ontology/knora-api/v2#>
PREFIX knora-simple-api: <http://api.knora.org/ontology/knora-api/simple/v2#>
PREFIX ll: <http://0.0.0.0:3333/ontology/0113/lumieres-lausanne/v2#>
CONSTRUCT {
?Person knora-api:isMainResource true .
} WHERE {
?Person a ll:Person .
?Person ll:isModern ?isModern .
?isModern knora-api:booleanValueAsBoolean ?isModern_Value .
FILTER(?isModern_Value = "false"^^xsd:boolean)
?Person ll:mayHaveBiography ?mayHaveBiography .
?mayHaveBiography knora-api:booleanValueAsBoolean ?mayHaveBiography_Value .
FILTER(?mayHaveBiography_Value = "true"^^xsd:boolean)
?Person ll:noticeIsCreated ?noticeIsCreated .
?noticeIsCreated knora-api:booleanValueAsBoolean ?noticeIsCreated_Value .
FILTER(?noticeIsCreated_Value = "true"^^xsd:boolean)
{
{
?Person ll:noticeCreationIsValid ?noticeCreationIsValid .
?noticeCreationIsValid knora-api:booleanValueAsBoolean ?noticeCreationIsValid_Value .
FILTER(?noticeCreationIsValid_Value = "true"^^xsd:boolean)
}
UNION
{
?Person ll:noticeModificationIsValid ?noticeModificationIsValid .
?noticeModificationIsValid knora-api:booleanValueAsBoolean ?noticeModificationIsValid_Value .
FILTER(?noticeModificationIsValid_Value = "true"^^xsd:boolean)
}
}
{
{
?Person ll:hasName ?hasName .
?hasName knora-api:valueAsString ?hasName_Value .
FILTER knora-api:match(?hasName_Value, "Mirab*")
}
UNION
{
?Person ll:hasPlaceBirth ?hasPlaceBirth .
?hasPlaceBirth knora-api:valueAsString ?hasPlaceBirth_Value .
FILTER knora-api:match(?hasPlaceBirth_Value, "Mirab*")
}
UNION
{
?Person ll:hasPlaceDeath ?hasPlaceDeath .
?hasPlaceDeath knora-api:valueAsString ?hasPlaceDeath_Value .
FILTER knora-api:match(?hasPlaceDeath_Value, "Mirab*")
}
UNION
{
?Person ll:hasPlaceOrigin ?hasPlaceOrigin .
?hasPlaceOrigin knora-api:valueAsString ?hasPlaceOrigin_Value .
FILTER knora-api:match(?hasPlaceOrigin_Value, "Mirab*")
}
UNION
{
?Person ll:hasBiography ?hasBiography .
?hasBiography knora-api:valueAsString ?hasBiography_Value .
FILTER knora-api:match(?hasBiography_Value, "Mirab*")
}
UNION
{
?Person ll:hasCivilStatus ?hasCivilStatus .
?hasCivilStatus knora-api:valueAsString ?hasCivilStatus_Value .
FILTER knora-api:match(?hasCivilStatus_Value, "Mirab*")
}
UNION
{
?Person ll:isInArchive ?isInArchive .
?isInArchive knora-api:valueAsString ?isInArchive_Value .
FILTER knora-api:match(?isInArchive_Value, "Mirab*")
}
UNION
{
?Person ll:hasCommentWork ?hasCommentWork .
?hasCommentWork knora-api:valueAsString ?hasCommentWork_Value .
FILTER knora-api:match(?hasCommentWork_Value, "Mirab*")
}
UNION
{
?Person ll:hasNote ?hasNote .
?hasNote a ll:Note .
?hasNote ll:hasDiffusionType ?hasDiffusionType_hasNote .
?hasDiffusionType_hasNote knora-api:booleanValueAsBoolean ?hasDiffusionType_hasNote_Value .
FILTER(?hasDiffusionType_hasNote_Value = "true"^^xsd:boolean)
?hasNote ll:noteHasText ?noteHasText_hasNote .
?noteHasText_hasNote knora-api:valueAsString ?noteHasText_hasNote_Value .
FILTER knora-api:match(?noteHasText_hasNote_Value, "Mirab*")
}
}
}
ORDER BY ASC(?hasName)
|
The sparql behind the scene that returns 4 resources: SELECT DISTINCT ?Person (GROUP_CONCAT(DISTINCT(?hasNote); SEPARATOR='') AS ?hasNote__Concat) (GROUP_CONCAT(DISTINCT(?hasPlaceOrigin); SEPARATOR='') AS ?hasPlaceOrigin__Concat) (GROUP_CONCAT(DISTINCT(?noticeModificationIsValid); SEPARATOR='') AS ?noticeModificationIsValid__Concat) (GROUP_CONCAT(DISTINCT(?hasPlaceBirth); SEPARATOR='') AS ?hasPlaceBirth__Concat) (GROUP_CONCAT(DISTINCT(?noticeIsCreated); SEPARATOR='') AS ?noticeIsCreated__Concat) (GROUP_CONCAT(DISTINCT(?hasPlaceDeath); SEPARATOR='') AS ?hasPlaceDeath__Concat) (GROUP_CONCAT(DISTINCT(?isModern); SEPARATOR='') AS ?isModern__Concat) (GROUP_CONCAT(DISTINCT(?hasBiography); SEPARATOR='') AS ?hasBiography__Concat) (GROUP_CONCAT(DISTINCT(?noteHasText_hasNote); SEPARATOR='') AS ?noteHasText_hasNote__Concat) (GROUP_CONCAT(DISTINCT(?isInArchive); SEPARATOR='') AS ?isInArchive__Concat) (GROUP_CONCAT(DISTINCT(?hasName); SEPARATOR='') AS ?hasName__Concat) (GROUP_CONCAT(DISTINCT(?Person__http00003333ontology0113lumiereslausannev2hasNote__hasNote__LinkValue); SEPARATOR='') AS ?Person__http00003333ontology0113lumiereslausannev2hasNote__hasNote__LinkValue__Concat) (GROUP_CONCAT(DISTINCT(?mayHaveBiography); SEPARATOR='') AS ?mayHaveBiography__Concat) (GROUP_CONCAT(DISTINCT(?noticeCreationIsValid); SEPARATOR='') AS ?noticeCreationIsValid__Concat) (GROUP_CONCAT(DISTINCT(?hasDiffusionType_hasNote); SEPARATOR='') AS ?hasDiffusionType_hasNote__Concat) (GROUP_CONCAT(DISTINCT(?hasCommentWork); SEPARATOR='') AS ?hasCommentWork__Concat) (GROUP_CONCAT(DISTINCT(?hasCivilStatus); SEPARATOR='') AS ?hasCivilStatus__Concat)
WHERE {
?Person <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.knora.org/ontology/knora-base#Resource> .
GRAPH <http://www.ontotext.com/explicit> {
?Person <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
?Person <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.knora.org/ontology/0113/lumieres-lausanne#Person> .
?Person <http://www.knora.org/ontology/0113/lumieres-lausanne#isModern> ?isModern .
GRAPH <http://www.ontotext.com/explicit> {
?isModern <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
?isModern <http://www.knora.org/ontology/knora-base#valueHasBoolean> ?isModern_Value .
?Person <http://www.knora.org/ontology/0113/lumieres-lausanne#mayHaveBiography> ?mayHaveBiography .
GRAPH <http://www.ontotext.com/explicit> {
?mayHaveBiography <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
?mayHaveBiography <http://www.knora.org/ontology/knora-base#valueHasBoolean> ?mayHaveBiography_Value .
?Person <http://www.knora.org/ontology/0113/lumieres-lausanne#noticeIsCreated> ?noticeIsCreated .
GRAPH <http://www.ontotext.com/explicit> {
?noticeIsCreated <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
?noticeIsCreated <http://www.knora.org/ontology/knora-base#valueHasBoolean> ?noticeIsCreated_Value .
{
?Person <http://www.knora.org/ontology/0113/lumieres-lausanne#noticeCreationIsValid> ?noticeCreationIsValid .
GRAPH <http://www.ontotext.com/explicit> {
?noticeCreationIsValid <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
?noticeCreationIsValid <http://www.knora.org/ontology/knora-base#valueHasBoolean> ?noticeCreationIsValid_Value .
FILTER((?noticeCreationIsValid_Value = "true"^^<http://www.w3.org/2001/XMLSchema#boolean>))
} UNION {
?Person <http://www.knora.org/ontology/0113/lumieres-lausanne#noticeModificationIsValid> ?noticeModificationIsValid .
GRAPH <http://www.ontotext.com/explicit> {
?noticeModificationIsValid <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
?noticeModificationIsValid <http://www.knora.org/ontology/knora-base#valueHasBoolean> ?noticeModificationIsValid_Value .
FILTER((?noticeModificationIsValid_Value = "true"^^<http://www.w3.org/2001/XMLSchema#boolean>))
}
{
?Person <http://www.knora.org/ontology/0113/lumieres-lausanne#hasName> ?hasName .
GRAPH <http://www.ontotext.com/explicit> {
?hasName <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
GRAPH <http://www.ontotext.com/explicit> {
?hasName <http://www.knora.org/ontology/knora-base#valueHasString> ?hasName__valueHasString .
}
?hasName <http://www.knora.org/ontology/knora-base#valueHasString> ?hasName_Value .
GRAPH <http://www.ontotext.com/explicit> {
?hasName_Value <http://www.ontotext.com/owlim/lucene#fullTextSearchIndex> "Mirab*"^^<http://www.w3.org/2001/XMLSchema#string> .
}
} UNION {
?Person <http://www.knora.org/ontology/0113/lumieres-lausanne#hasPlaceBirth> ?hasPlaceBirth .
GRAPH <http://www.ontotext.com/explicit> {
?hasPlaceBirth <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
?hasPlaceBirth <http://www.knora.org/ontology/knora-base#valueHasString> ?hasPlaceBirth_Value .
GRAPH <http://www.ontotext.com/explicit> {
?hasPlaceBirth_Value <http://www.ontotext.com/owlim/lucene#fullTextSearchIndex> "Mirab*"^^<http://www.w3.org/2001/XMLSchema#string> .
}
} UNION {
?Person <http://www.knora.org/ontology/0113/lumieres-lausanne#hasPlaceDeath> ?hasPlaceDeath .
GRAPH <http://www.ontotext.com/explicit> {
?hasPlaceDeath <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
?hasPlaceDeath <http://www.knora.org/ontology/knora-base#valueHasString> ?hasPlaceDeath_Value .
GRAPH <http://www.ontotext.com/explicit> {
?hasPlaceDeath_Value <http://www.ontotext.com/owlim/lucene#fullTextSearchIndex> "Mirab*"^^<http://www.w3.org/2001/XMLSchema#string> .
}
} UNION {
?Person <http://www.knora.org/ontology/0113/lumieres-lausanne#hasPlaceOrigin> ?hasPlaceOrigin .
GRAPH <http://www.ontotext.com/explicit> {
?hasPlaceOrigin <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
?hasPlaceOrigin <http://www.knora.org/ontology/knora-base#valueHasString> ?hasPlaceOrigin_Value .
GRAPH <http://www.ontotext.com/explicit> {
?hasPlaceOrigin_Value <http://www.ontotext.com/owlim/lucene#fullTextSearchIndex> "Mirab*"^^<http://www.w3.org/2001/XMLSchema#string> .
}
} UNION {
?Person <http://www.knora.org/ontology/0113/lumieres-lausanne#hasBiography> ?hasBiography .
GRAPH <http://www.ontotext.com/explicit> {
?hasBiography <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
?hasBiography <http://www.knora.org/ontology/knora-base#valueHasString> ?hasBiography_Value .
GRAPH <http://www.ontotext.com/explicit> {
?hasBiography_Value <http://www.ontotext.com/owlim/lucene#fullTextSearchIndex> "Mirab*"^^<http://www.w3.org/2001/XMLSchema#string> .
}
} UNION {
?Person <http://www.knora.org/ontology/0113/lumieres-lausanne#hasCivilStatus> ?hasCivilStatus .
GRAPH <http://www.ontotext.com/explicit> {
?hasCivilStatus <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
?hasCivilStatus <http://www.knora.org/ontology/knora-base#valueHasString> ?hasCivilStatus_Value .
GRAPH <http://www.ontotext.com/explicit> {
?hasCivilStatus_Value <http://www.ontotext.com/owlim/lucene#fullTextSearchIndex> "Mirab*"^^<http://www.w3.org/2001/XMLSchema#string> .
}
} UNION {
?Person <http://www.knora.org/ontology/0113/lumieres-lausanne#isInArchive> ?isInArchive .
GRAPH <http://www.ontotext.com/explicit> {
?isInArchive <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
?isInArchive <http://www.knora.org/ontology/knora-base#valueHasString> ?isInArchive_Value .
GRAPH <http://www.ontotext.com/explicit> {
?isInArchive_Value <http://www.ontotext.com/owlim/lucene#fullTextSearchIndex> "Mirab*"^^<http://www.w3.org/2001/XMLSchema#string> .
}
} UNION {
?Person <http://www.knora.org/ontology/0113/lumieres-lausanne#hasCommentWork> ?hasCommentWork .
GRAPH <http://www.ontotext.com/explicit> {
?hasCommentWork <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
?hasCommentWork <http://www.knora.org/ontology/knora-base#valueHasString> ?hasCommentWork_Value .
GRAPH <http://www.ontotext.com/explicit> {
?hasCommentWork_Value <http://www.ontotext.com/owlim/lucene#fullTextSearchIndex> "Mirab*"^^<http://www.w3.org/2001/XMLSchema#string> .
}
} UNION {
?Person <http://www.knora.org/ontology/0113/lumieres-lausanne#hasNote> ?hasNote .
?Person <http://www.knora.org/ontology/0113/lumieres-lausanne#hasNoteValue> ?Person__http00003333ontology0113lumiereslausannev2hasNote__hasNote__LinkValue .
GRAPH <http://www.ontotext.com/explicit> {
?Person__http00003333ontology0113lumiereslausannev2hasNote__hasNote__LinkValue <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.knora.org/ontology/knora-base#LinkValue> .
}
GRAPH <http://www.ontotext.com/explicit> {
?Person__http00003333ontology0113lumiereslausannev2hasNote__hasNote__LinkValue <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
GRAPH <http://www.ontotext.com/explicit> {
?Person__http00003333ontology0113lumiereslausannev2hasNote__hasNote__LinkValue <http://www.w3.org/1999/02/22-rdf-syntax-ns#subject> ?Person .
}
GRAPH <http://www.ontotext.com/explicit> {
?Person__http00003333ontology0113lumiereslausannev2hasNote__hasNote__LinkValue <http://www.w3.org/1999/02/22-rdf-syntax-ns#object> ?hasNote .
}
?hasNote <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.knora.org/ontology/knora-base#Resource> .
GRAPH <http://www.ontotext.com/explicit> {
?hasNote <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
?hasNote <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.knora.org/ontology/0113/lumieres-lausanne#Note> .
?hasNote <http://www.knora.org/ontology/0113/lumieres-lausanne#hasDiffusionType> ?hasDiffusionType_hasNote .
GRAPH <http://www.ontotext.com/explicit> {
?hasDiffusionType_hasNote <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
?hasDiffusionType_hasNote <http://www.knora.org/ontology/knora-base#valueHasBoolean> ?hasDiffusionType_hasNote_Value .
?hasNote <http://www.knora.org/ontology/0113/lumieres-lausanne#noteHasText> ?noteHasText_hasNote .
GRAPH <http://www.ontotext.com/explicit> {
?noteHasText_hasNote <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
?noteHasText_hasNote <http://www.knora.org/ontology/knora-base#valueHasString> ?noteHasText_hasNote_Value .
FILTER((?hasDiffusionType_hasNote_Value = "true"^^<http://www.w3.org/2001/XMLSchema#boolean>))
GRAPH <http://www.ontotext.com/explicit> {
?noteHasText_hasNote_Value <http://www.ontotext.com/owlim/lucene#fullTextSearchIndex> "Mirab*"^^<http://www.w3.org/2001/XMLSchema#string> .
}
}
FILTER((?isModern_Value = "false"^^<http://www.w3.org/2001/XMLSchema#boolean>))
FILTER((?mayHaveBiography_Value = "true"^^<http://www.w3.org/2001/XMLSchema#boolean>))
FILTER((?noticeIsCreated_Value = "true"^^<http://www.w3.org/2001/XMLSchema#boolean>))
}
GROUP BY ?Person ?hasName__valueHasString
ORDER BY ASC(?hasName__valueHasString) ASC(?Person)
LIMIT 25 With @loicjaouen we suspect the We get a correct result with a gravsearch query without |
Concerning the previous sparql's query, do you really need to get all these columns |
Gravsearch generates two queries from a given input query: a prequery and a main query (see https://docs.knora.org/paradox/05-internals/design/api-v2/gravsearch.html#transformation-of-a-gravsearch-query). The prequery returns Iris of main resources, dependent resources and values that matched the criteria given in the WHERE clause. Per matching main resource, one row is returned. Iris of dependent resources and values are concatenated because there could be multiple matches. This is achieved by grouping by the main resource. If I remember correctly, additional search criteria has to be included in
Do you think the problem is the results returned by the triplestore or the processing of the results in Knora? |
I am not sure what the triplestore is supposed to return, but we ask for: SELECT DISTINCT ?Person
...
GROUP BY ?Person ?hasName__valueHasString and we receive duplicated If sparql or graphdb says that it is so (there is one index per (then knowing why we have two different |
Does If so, I can confirm that Gravsearch won't work correctly: |
equals to 1:
|
But then this should be impossible
|
Could you check if there is more than one |
we can look at that in a second stage, right now what do you think of having a: SELECT DISTINCT ?Person
...
GROUP BY ?Person giving the right answer and a: SELECT DISTINCT ?Person
...
GROUP BY ?Person ?hasName__valueHasString giving duplicates? |
The only reason I can think if this that Could you make a full resource request for the person resource for which you are getting multiple results? |
Also could you please check which Iris are returned for
|
So unfortunately the data is not online right now. The above query returns 4 Person
the duplicated resource is:
where there is only one |
the duplicated resource comes once with an empty that's with the request:
|
the same the request with only a
returns no duplicate and a non-empty |
for the record, that value is:
|
we are getting closer now... |
if we execute this sparql request:
we get three properties matching: |
Could give me a trig file to download (all ontologies and data in one file) so I can reproduce it locally? |
Today is my day off, I can try it later this week. |
I have the suspicion that you are getting the duplicates because the sort criterion is contained in a PREFIX knora-api: <http://api.knora.org/ontology/knora-api/v2#>
PREFIX knora-simple-api: <http://api.knora.org/ontology/knora-api/simple/v2#>
PREFIX ll: <http://0.0.0.0:3333/ontology/0113/lumieres-lausanne/v2#>
CONSTRUCT {
?Person knora-api:isMainResource true .
} WHERE {
?Person a ll:Person .
?Person ll:isModern ?isModern .
?isModern knora-api:booleanValueAsBoolean ?isModern_Value .
FILTER(?isModern_Value = "false"^^xsd:boolean)
?Person ll:mayHaveBiography ?mayHaveBiography .
?mayHaveBiography knora-api:booleanValueAsBoolean ?mayHaveBiography_Value .
FILTER(?mayHaveBiography_Value = "true"^^xsd:boolean)
?Person ll:noticeIsCreated ?noticeIsCreated .
?noticeIsCreated knora-api:booleanValueAsBoolean ?noticeIsCreated_Value .
FILTER(?noticeIsCreated_Value = "true"^^xsd:boolean)
?Person ll:hasName ?hasName .
?hasName knora-api:valueAsString ?hasName_Value .
FILTER knora-api:match(?hasName_Value, "Mirab*")
{
{
?Person ll:noticeCreationIsValid ?noticeCreationIsValid .
?noticeCreationIsValid knora-api:booleanValueAsBoolean ?noticeCreationIsValid_Value .
FILTER(?noticeCreationIsValid_Value = "true"^^xsd:boolean)
}
UNION
{
?Person ll:noticeModificationIsValid ?noticeModificationIsValid .
?noticeModificationIsValid knora-api:booleanValueAsBoolean ?noticeModificationIsValid_Value .
FILTER(?noticeModificationIsValid_Value = "true"^^xsd:boolean)
}
}
{
{
?Person ll:hasPlaceBirth ?hasPlaceBirth .
?hasPlaceBirth knora-api:valueAsString ?hasPlaceBirth_Value .
FILTER knora-api:match(?hasPlaceBirth_Value, "Mirab*")
}
UNION
{
?Person ll:hasPlaceDeath ?hasPlaceDeath .
?hasPlaceDeath knora-api:valueAsString ?hasPlaceDeath_Value .
FILTER knora-api:match(?hasPlaceDeath_Value, "Mirab*")
}
UNION
{
?Person ll:hasPlaceOrigin ?hasPlaceOrigin .
?hasPlaceOrigin knora-api:valueAsString ?hasPlaceOrigin_Value .
FILTER knora-api:match(?hasPlaceOrigin_Value, "Mirab*")
}
UNION
{
?Person ll:hasBiography ?hasBiography .
?hasBiography knora-api:valueAsString ?hasBiography_Value .
FILTER knora-api:match(?hasBiography_Value, "Mirab*")
}
UNION
{
?Person ll:hasCivilStatus ?hasCivilStatus .
?hasCivilStatus knora-api:valueAsString ?hasCivilStatus_Value .
FILTER knora-api:match(?hasCivilStatus_Value, "Mirab*")
}
UNION
{
?Person ll:isInArchive ?isInArchive .
?isInArchive knora-api:valueAsString ?isInArchive_Value .
FILTER knora-api:match(?isInArchive_Value, "Mirab*")
}
UNION
{
?Person ll:hasCommentWork ?hasCommentWork .
?hasCommentWork knora-api:valueAsString ?hasCommentWork_Value .
FILTER knora-api:match(?hasCommentWork_Value, "Mirab*")
}
UNION
{
?Person ll:hasNote ?hasNote .
?hasNote a ll:Note .
?hasNote ll:hasDiffusionType ?hasDiffusionType_hasNote .
?hasDiffusionType_hasNote knora-api:booleanValueAsBoolean ?hasDiffusionType_hasNote_Value .
FILTER(?hasDiffusionType_hasNote_Value = "true"^^xsd:boolean)
?hasNote ll:noteHasText ?noteHasText_hasNote .
?noteHasText_hasNote knora-api:valueAsString ?noteHasText_hasNote_Value .
FILTER knora-api:match(?noteHasText_hasNote_Value, "Mirab*")
}
}
}
ORDER BY ASC(?hasName) I am getting one result ("http://rdfh.ch/0113/MKE_5sRNTy6N2H0JTV3Now"). |
When I run the following query SELECT DISTINCT ?Person ?hasName__valueHasString
WHERE {
?Person <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.knora.org/ontology/knora-base#Resource> .
GRAPH <http://www.ontotext.com/explicit> {
?Person <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
?Person <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.knora.org/ontology/0113/lumieres-lausanne#Person> .
?Person <http://www.knora.org/ontology/0113/lumieres-lausanne#isModern> ?isModern .
GRAPH <http://www.ontotext.com/explicit> {
?isModern <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
?isModern <http://www.knora.org/ontology/knora-base#valueHasBoolean> ?isModern_Value .
?Person <http://www.knora.org/ontology/0113/lumieres-lausanne#mayHaveBiography> ?mayHaveBiography .
GRAPH <http://www.ontotext.com/explicit> {
?mayHaveBiography <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
?mayHaveBiography <http://www.knora.org/ontology/knora-base#valueHasBoolean> ?mayHaveBiography_Value .
?Person <http://www.knora.org/ontology/0113/lumieres-lausanne#noticeIsCreated> ?noticeIsCreated .
GRAPH <http://www.ontotext.com/explicit> {
?noticeIsCreated <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
?noticeIsCreated <http://www.knora.org/ontology/knora-base#valueHasBoolean> ?noticeIsCreated_Value .
{
?Person <http://www.knora.org/ontology/0113/lumieres-lausanne#noticeCreationIsValid> ?noticeCreationIsValid .
GRAPH <http://www.ontotext.com/explicit> {
?noticeCreationIsValid <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
?noticeCreationIsValid <http://www.knora.org/ontology/knora-base#valueHasBoolean> ?noticeCreationIsValid_Value .
FILTER((?noticeCreationIsValid_Value = "true"^^<http://www.w3.org/2001/XMLSchema#boolean>))
} UNION {
?Person <http://www.knora.org/ontology/0113/lumieres-lausanne#noticeModificationIsValid> ?noticeModificationIsValid .
GRAPH <http://www.ontotext.com/explicit> {
?noticeModificationIsValid <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
?noticeModificationIsValid <http://www.knora.org/ontology/knora-base#valueHasBoolean> ?noticeModificationIsValid_Value .
FILTER((?noticeModificationIsValid_Value = "true"^^<http://www.w3.org/2001/XMLSchema#boolean>))
}
{
?Person <http://www.knora.org/ontology/0113/lumieres-lausanne#hasName> ?hasName .
GRAPH <http://www.ontotext.com/explicit> {
?hasName <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
GRAPH <http://www.ontotext.com/explicit> {
?hasName <http://www.knora.org/ontology/knora-base#valueHasString> ?hasName__valueHasString .
}
?hasName <http://www.knora.org/ontology/knora-base#valueHasString> ?hasName_Value .
GRAPH <http://www.ontotext.com/explicit> {
?hasName_Value <http://www.ontotext.com/owlim/lucene#fullTextSearchIndex> "Mirab*"^^<http://www.w3.org/2001/XMLSchema#string> .
}
} UNION {
?Person <http://www.knora.org/ontology/0113/lumieres-lausanne#hasPlaceBirth> ?hasPlaceBirth .
GRAPH <http://www.ontotext.com/explicit> {
?hasPlaceBirth <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
?hasPlaceBirth <http://www.knora.org/ontology/knora-base#valueHasString> ?hasPlaceBirth_Value .
GRAPH <http://www.ontotext.com/explicit> {
?hasPlaceBirth_Value <http://www.ontotext.com/owlim/lucene#fullTextSearchIndex> "Mirab*"^^<http://www.w3.org/2001/XMLSchema#string> .
}
} UNION {
?Person <http://www.knora.org/ontology/0113/lumieres-lausanne#hasPlaceDeath> ?hasPlaceDeath .
GRAPH <http://www.ontotext.com/explicit> {
?hasPlaceDeath <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
?hasPlaceDeath <http://www.knora.org/ontology/knora-base#valueHasString> ?hasPlaceDeath_Value .
GRAPH <http://www.ontotext.com/explicit> {
?hasPlaceDeath_Value <http://www.ontotext.com/owlim/lucene#fullTextSearchIndex> "Mirab*"^^<http://www.w3.org/2001/XMLSchema#string> .
}
} UNION {
?Person <http://www.knora.org/ontology/0113/lumieres-lausanne#hasPlaceOrigin> ?hasPlaceOrigin .
GRAPH <http://www.ontotext.com/explicit> {
?hasPlaceOrigin <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
?hasPlaceOrigin <http://www.knora.org/ontology/knora-base#valueHasString> ?hasPlaceOrigin_Value .
GRAPH <http://www.ontotext.com/explicit> {
?hasPlaceOrigin_Value <http://www.ontotext.com/owlim/lucene#fullTextSearchIndex> "Mirab*"^^<http://www.w3.org/2001/XMLSchema#string> .
}
} UNION {
?Person <http://www.knora.org/ontology/0113/lumieres-lausanne#hasBiography> ?hasBiography .
GRAPH <http://www.ontotext.com/explicit> {
?hasBiography <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
?hasBiography <http://www.knora.org/ontology/knora-base#valueHasString> ?hasBiography_Value .
GRAPH <http://www.ontotext.com/explicit> {
?hasBiography_Value <http://www.ontotext.com/owlim/lucene#fullTextSearchIndex> "Mirab*"^^<http://www.w3.org/2001/XMLSchema#string> .
}
} UNION {
?Person <http://www.knora.org/ontology/0113/lumieres-lausanne#hasCivilStatus> ?hasCivilStatus .
GRAPH <http://www.ontotext.com/explicit> {
?hasCivilStatus <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
?hasCivilStatus <http://www.knora.org/ontology/knora-base#valueHasString> ?hasCivilStatus_Value .
GRAPH <http://www.ontotext.com/explicit> {
?hasCivilStatus_Value <http://www.ontotext.com/owlim/lucene#fullTextSearchIndex> "Mirab*"^^<http://www.w3.org/2001/XMLSchema#string> .
}
} UNION {
?Person <http://www.knora.org/ontology/0113/lumieres-lausanne#isInArchive> ?isInArchive .
GRAPH <http://www.ontotext.com/explicit> {
?isInArchive <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
?isInArchive <http://www.knora.org/ontology/knora-base#valueHasString> ?isInArchive_Value .
GRAPH <http://www.ontotext.com/explicit> {
?isInArchive_Value <http://www.ontotext.com/owlim/lucene#fullTextSearchIndex> "Mirab*"^^<http://www.w3.org/2001/XMLSchema#string> .
}
} UNION {
?Person <http://www.knora.org/ontology/0113/lumieres-lausanne#hasCommentWork> ?hasCommentWork .
GRAPH <http://www.ontotext.com/explicit> {
?hasCommentWork <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
?hasCommentWork <http://www.knora.org/ontology/knora-base#valueHasString> ?hasCommentWork_Value .
GRAPH <http://www.ontotext.com/explicit> {
?hasCommentWork_Value <http://www.ontotext.com/owlim/lucene#fullTextSearchIndex> "Mirab*"^^<http://www.w3.org/2001/XMLSchema#string> .
}
} UNION {
?Person <http://www.knora.org/ontology/0113/lumieres-lausanne#hasNote> ?hasNote .
?Person <http://www.knora.org/ontology/0113/lumieres-lausanne#hasNoteValue> ?Person__http00003333ontology0113lumiereslausannev2hasNote__hasNote__LinkValue .
GRAPH <http://www.ontotext.com/explicit> {
?Person__http00003333ontology0113lumiereslausannev2hasNote__hasNote__LinkValue <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.knora.org/ontology/knora-base#LinkValue> .
}
GRAPH <http://www.ontotext.com/explicit> {
?Person__http00003333ontology0113lumiereslausannev2hasNote__hasNote__LinkValue <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
GRAPH <http://www.ontotext.com/explicit> {
?Person__http00003333ontology0113lumiereslausannev2hasNote__hasNote__LinkValue <http://www.w3.org/1999/02/22-rdf-syntax-ns#subject> ?Person .
}
GRAPH <http://www.ontotext.com/explicit> {
?Person__http00003333ontology0113lumiereslausannev2hasNote__hasNote__LinkValue <http://www.w3.org/1999/02/22-rdf-syntax-ns#object> ?hasNote .
}
?hasNote <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.knora.org/ontology/knora-base#Resource> .
GRAPH <http://www.ontotext.com/explicit> {
?hasNote <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
?hasNote <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.knora.org/ontology/0113/lumieres-lausanne#Note> .
?hasNote <http://www.knora.org/ontology/0113/lumieres-lausanne#hasDiffusionType> ?hasDiffusionType_hasNote .
GRAPH <http://www.ontotext.com/explicit> {
?hasDiffusionType_hasNote <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
?hasDiffusionType_hasNote <http://www.knora.org/ontology/knora-base#valueHasBoolean> ?hasDiffusionType_hasNote_Value .
?hasNote <http://www.knora.org/ontology/0113/lumieres-lausanne#noteHasText> ?noteHasText_hasNote .
GRAPH <http://www.ontotext.com/explicit> {
?noteHasText_hasNote <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
?noteHasText_hasNote <http://www.knora.org/ontology/knora-base#valueHasString> ?noteHasText_hasNote_Value .
FILTER((?hasDiffusionType_hasNote_Value = "true"^^<http://www.w3.org/2001/XMLSchema#boolean>))
GRAPH <http://www.ontotext.com/explicit> {
?noteHasText_hasNote_Value <http://www.ontotext.com/owlim/lucene#fullTextSearchIndex> "Mirab*"^^<http://www.w3.org/2001/XMLSchema#string> .
}
}
FILTER((?isModern_Value = "false"^^<http://www.w3.org/2001/XMLSchema#boolean>))
FILTER((?mayHaveBiography_Value = "true"^^<http://www.w3.org/2001/XMLSchema#boolean>))
FILTER((?noticeIsCreated_Value = "true"^^<http://www.w3.org/2001/XMLSchema#boolean>))
}
LIMIT 25
I get this result: "http://rdfh.ch/0113/MKE_5sRNTy6N2H0JTV3Now" is the only resource that has a matching "hasName", the others don't (thus returning nothing for But I don't understand why this is also the case for "http://rdfh.ch/0113/MKE_5sRNTy6N2H0JTV3Now", as if its UNION once matched and once did not. @benjamingeer Scoping issue with UNION? |
What I've read is that a https://wiki.blazegraph.com/wiki/index.php/SPARQL_Bottom_Up_Semantics#UNIONs But sometimes it seems to work anyway, e.g. in the |
If I had the data I could play with it and try to figure out what's going on. |
I have the data 🙂 will provide it tomorrow |
@benjamingeer I shared the trig file with you on switchdrive How I loaded it into my local graphDB:
|
Why do I have to deactivate consistency checking? Is the issue caused by inconsistent data? |
once you unpack the file, you'll see that it is very big (1.91 GB). I figured it would take too much time with consistency checking. And yes, I spotted a problem with an empty integer value. |
so each union would have to ask for the common set of triplets otherwise we build different sub-graph for matching criteria? a simplified version of the request on two properties, name and biography, we have: SELECT DISTINCT ?Person ?hasName__valueHasString ?hasName ?hasName_Value
WHERE {
?Person <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.knora.org/ontology/knora-base#Resource> .
{
?Person <http://www.knora.org/ontology/0113/lumieres-lausanne#hasName> ?hasName .
?Person <http://www.knora.org/ontology/0113/lumieres-lausanne#hasBiography> ?hasBiography .
?hasBiography <http://www.knora.org/ontology/knora-base#valueHasString> ?hasBiography_Value .
GRAPH <http://www.ontotext.com/explicit> {
?hasName <http://www.knora.org/ontology/knora-base#valueHasString> ?hasName__valueHasString .
}
?hasName <http://www.knora.org/ontology/knora-base#valueHasString> ?hasName_Value .
GRAPH <http://www.ontotext.com/explicit> {
?hasName_Value <http://www.ontotext.com/owlim/lucene#fullTextSearchIndex> "Mirab*"^^<http://www.w3.org/2001/XMLSchema#string> .
}
} UNION {
?Person <http://www.knora.org/ontology/0113/lumieres-lausanne#hasName> ?hasName .
?hasName <http://www.knora.org/ontology/knora-base#valueHasString> ?hasName__valueHasString .
?hasName <http://www.knora.org/ontology/knora-base#valueHasString> ?hasName_Value .
?Person <http://www.knora.org/ontology/0113/lumieres-lausanne#hasBiography> ?hasBiography .
GRAPH <http://www.ontotext.com/explicit> {
?hasBiography <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
?hasBiography <http://www.knora.org/ontology/knora-base#valueHasString> ?hasBiography_Value .
GRAPH <http://www.ontotext.com/explicit> {
?hasBiography_Value <http://www.ontotext.com/owlim/lucene#fullTextSearchIndex> "Mirab*"^^<http://www.w3.org/2001/XMLSchema#string> .
}
}
}
LIMIT 25 returning no duplicate SELECT DISTINCT ?Person ?hasName__valueHasString ?hasName ?hasName_Value
WHERE {
?Person <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.knora.org/ontology/knora-base#Resource> .
{
?Person <http://www.knora.org/ontology/0113/lumieres-lausanne#hasName> ?hasName .
GRAPH <http://www.ontotext.com/explicit> {
?hasName <http://www.knora.org/ontology/knora-base#valueHasString> ?hasName__valueHasString .
}
?hasName <http://www.knora.org/ontology/knora-base#valueHasString> ?hasName_Value .
GRAPH <http://www.ontotext.com/explicit> {
?hasName_Value <http://www.ontotext.com/owlim/lucene#fullTextSearchIndex> "Mirab*"^^<http://www.w3.org/2001/XMLSchema#string> .
}
} UNION {
?Person <http://www.knora.org/ontology/0113/lumieres-lausanne#hasBiography> ?hasBiography .
GRAPH <http://www.ontotext.com/explicit> {
?hasBiography <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
?hasBiography <http://www.knora.org/ontology/knora-base#valueHasString> ?hasBiography_Value .
GRAPH <http://www.ontotext.com/explicit> {
?hasBiography_Value <http://www.ontotext.com/owlim/lucene#fullTextSearchIndex> "Mirab*"^^<http://www.w3.org/2001/XMLSchema#string> .
}
}
}
LIMIT 25 returns duplicates and empty fields. |
I think so. Could we have a data file just containing the data needed to reproduce this issue? |
it is a union of two subgraphs, the first one matches the name, the second the biography, if we set the both properties on both subgraphs, the union does it works and otherwise, the name is understood as a new value (empty) and adds a duplicated line for the same resource. |
maybe the problem is that we do a select and not a construct |
I don't understand. I think a |
Wouldn't it make sense to only use a non-optional property as a sort criterion? |
@benjamingeer did you get the data? it makes a difference because select adds two paths of multiple lengths and construct adds triples and it fills the missing elements of the path with empty values. the query: SELECT DISTINCT ?Person ?hasName__valueHasString ?hasName ?hasName_Value
WHERE {
?Person <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.knora.org/ontology/knora-base#Resource> .
{
?Person <http://www.knora.org/ontology/0113/lumieres-lausanne#hasName> ?hasName .
GRAPH <http://www.ontotext.com/explicit> {
?hasName <http://www.knora.org/ontology/knora-base#valueHasString> ?hasName__valueHasString .
}
?hasName <http://www.knora.org/ontology/knora-base#valueHasString> ?hasName_Value .
GRAPH <http://www.ontotext.com/explicit> {
?hasName_Value <http://www.ontotext.com/owlim/lucene#fullTextSearchIndex> "Mirab*"^^<http://www.w3.org/2001/XMLSchema#string> .
}
} UNION {
?Person <http://www.knora.org/ontology/0113/lumieres-lausanne#hasBiography> ?hasBiography .
GRAPH <http://www.ontotext.com/explicit> {
?hasBiography <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
?hasBiography <http://www.knora.org/ontology/knora-base#valueHasString> ?hasBiography_Value .
GRAPH <http://www.ontotext.com/explicit> {
?hasBiography_Value <http://www.ontotext.com/owlim/lucene#fullTextSearchIndex> "Mirab*"^^<http://www.w3.org/2001/XMLSchema#string> .
}
}
}
LIMIT 25 |
when filling the same properties on the two subgraphs of the union, we get: SELECT DISTINCT ?Person ?hasName__valueHasString ?hasName ?hasName_Value
WHERE {
?Person <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.knora.org/ontology/knora-base#Resource> .
{
?Person <http://www.knora.org/ontology/0113/lumieres-lausanne#hasName> ?hasName .
?Person <http://www.knora.org/ontology/0113/lumieres-lausanne#hasBiography> ?hasBiography .
?hasBiography <http://www.knora.org/ontology/knora-base#valueHasString> ?hasBiography_Value .
GRAPH <http://www.ontotext.com/explicit> {
?hasName <http://www.knora.org/ontology/knora-base#valueHasString> ?hasName__valueHasString .
}
?hasName <http://www.knora.org/ontology/knora-base#valueHasString> ?hasName_Value .
GRAPH <http://www.ontotext.com/explicit> {
?hasName_Value <http://www.ontotext.com/owlim/lucene#fullTextSearchIndex> "Mirab*"^^<http://www.w3.org/2001/XMLSchema#string> .
}
} UNION {
?Person <http://www.knora.org/ontology/0113/lumieres-lausanne#hasName> ?hasName .
?hasName <http://www.knora.org/ontology/knora-base#valueHasString> ?hasName__valueHasString .
?hasName <http://www.knora.org/ontology/knora-base#valueHasString> ?hasName_Value .
?Person <http://www.knora.org/ontology/0113/lumieres-lausanne#hasBiography> ?hasBiography .
GRAPH <http://www.ontotext.com/explicit> {
?hasBiography <http://www.knora.org/ontology/knora-base#isDeleted> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
?hasBiography <http://www.knora.org/ontology/knora-base#valueHasString> ?hasBiography_Value .
GRAPH <http://www.ontotext.com/explicit> {
?hasBiography_Value <http://www.ontotext.com/owlim/lucene#fullTextSearchIndex> "Mirab*"^^<http://www.w3.org/2001/XMLSchema#string> .
}
}
}
LIMIT 25
|
Tobias said you gave him a 2 GB file and he had to turn off consistency checking to load it in a reasonable amount of time. I would like to be able to reproduce this issue with consistency checking turned on, in case the problem is actually caused by inconsistent data. Therefore I'm asking for a smaller data file, containing just the resources that you're searching for.
I'm not sure I understand what you mean by path. In both Without having your data, I can guess that in your first query above, the first branch of the |
exactly, that's what I meant |
So what should we do about this? Should we just add something about it to the documentation? |
Thinning out existing data in a 2G set is messy. What we do about it... On this request, we have skipped the gravsearch to look directly at the sparql request, we will work out our gravsearch request to see if we get to the a working generated sparql (which we should). The comment to add would be more something like "gravsearch generates sparql, make sure you understand sparql logic prior to using gravsearch", or you might rewrite sparql documentation in the gravsearch documentation. For this specific case, I think there is a bit more to add because it is still strange to send a request and get different result whether we ask for the results or ask for a |
That problem seems to happen again and again. There are already books about SPARQL, but maybe we could add a section mentioning common misunderstandings, surprising aspects of SPARQL, things like that.
Is there a way we could change the generated SPARQL so they'd return the same result? |
We need the For now, can you change your Gravsearch query so that it binds the necessary variables in the For a longer-term solution, I think this needs a bit more thought and will take some time. Maybe we could actually analyse the query and reject it if the same variables aren't bound in each branch of the |
sorry, I deleted my comment, it was something like:
in the select statement, by not adding the variables that end up as unbound for some of the union subgraphs: - SELECT DISTINCT ?Person (GROUP_CONCAT(DISTINCT(?hasNote); SEPARATOR='')
+ SELECT DISTINCT ?Person |
don't forget this probably related issue #1575 |
That's an interesting idea, definitely worth thinking about. |
For now can you change your Gravsearch query so it includes the additional criteria and works the way you want? |
I don't think so right now. I will probably disable the |
Is that possible to get duplicated resources in a result of gravsearch query? In my test, 4 resources, one duplicated.
I suppose this is not normal because if I use the same query with the
/count
route I get the correct result, that is"schema:numberOfItems": 3
.The text was updated successfully, but these errors were encountered: