Skip to content
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

Kbss cvut/termit UI#544 extend fts #306

Merged
merged 3 commits into from
Oct 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 17 additions & 5 deletions profile/graphdb/query/fulltextsearch.rq
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ PREFIX inst: <http://www.ontotext.com/connectors/lucene/instance#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX dc: <http://purl.org/dc/terms/>
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>

SELECT DISTINCT ?entity ?label ?vocabularyUri ?state ?type ?snippetField ?snippetText ?score {
SELECT DISTINCT ?entity ?label ?description ?vocabularyUri ?state ?type ?snippetField ?snippetText ?score {
{
?search a inst:label_index .
}
Expand All @@ -17,12 +18,21 @@ SELECT DISTINCT ?entity ?label ?vocabularyUri ?state ?type ?snippetField ?snippe
?search a inst:defcom_index .
}
{
?entity rdfs:label ?label .
?entity skos:prefLabel ?label .
OPTIONAL {
?entity skos:definition ?definition .
}
OPTIONAL {
?entity skos:scopeNote ?scopeNote .
}
} UNION {
?entity dc:title ?label .
OPTIONAL {
?entity dc:description ?dcDescription .
}
}
?search :query ?wildCardSearchString ;
:snippetSize 2000 ;
:snippetSize 250 ;
:entities ?entity .
?entity a ?type ;
:score ?initScore ;
Expand All @@ -38,7 +48,9 @@ SELECT DISTINCT ?entity ?label ?vocabularyUri ?state ?type ?snippetField ?snippe
FILTER (?type = ?term || ?type = ?vocabulary)
FILTER NOT EXISTS { ?entity a ?snapshot . }
FILTER (lang(?label) = ?langTag)
BIND(IF(lcase(str(?snippetText)) = lcase(str(?splitExactMatch)), ?initScore * 2, IF(CONTAINS(lcase(str(?snippetText)), ?searchString), IF(?snippetField = "label", ?initScore * 1.5, ?initScore), ?initScore)) as ?exactMatchScore)
BIND(IF(?snippetField = "label", ?exactMatchScore * 2, IF(?snippetField = "definition", ?exactMatchScore * 1.2, ?exactMatchScore)) as ?score)
BIND(COALESCE(?definition, COALESCE(?scopeNote, ?dcDescription)) AS ?description)
FILTER (!BOUND(?description) || lang(?description) = ?langTag)
BIND(IF(lcase(str(?snippetText)) = lcase(str(?splitExactMatch)), ?initScore * 2, IF(CONTAINS(lcase(str(?snippetText)), ?searchString), IF(?snippetField = "prefLabel", ?initScore * 1.5, ?initScore), ?initScore)) as ?exactMatchScore)
BIND(IF(?snippetField = "prefLabel", ?exactMatchScore * 2, IF(?snippetField = "definition", ?exactMatchScore * 1.2, ?exactMatchScore)) as ?score)
}
ORDER BY desc(?score)
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import cz.cvut.kbss.jopa.model.annotations.SparqlResultSetMapping;
import cz.cvut.kbss.jopa.model.annotations.Types;
import cz.cvut.kbss.jopa.model.annotations.VariableResult;
import cz.cvut.kbss.jopa.vocabulary.DC;
import cz.cvut.kbss.jopa.vocabulary.RDFS;
import cz.cvut.kbss.termit.model.util.HasIdentifier;
import cz.cvut.kbss.termit.model.util.HasTypes;
Expand All @@ -41,6 +42,7 @@
variables = {
@VariableResult(name = "entity", type = URI.class),
@VariableResult(name = "label", type = String.class),
@VariableResult(name = "description", type = String.class),
@VariableResult(name = "vocabularyUri", type = URI.class),
@VariableResult(name = "state", type = URI.class),
@VariableResult(name = "type", type = String.class),
Expand All @@ -59,6 +61,10 @@ public class FullTextSearchResult implements HasIdentifier, HasTypes, Serializab
@OWLAnnotationProperty(iri = RDFS.LABEL)
private String label;

// This could be term definition, scope note or vocabulary description
@OWLAnnotationProperty(iri = DC.Terms.DESCRIPTION)
private String description;

@OWLDataProperty(iri = Vocabulary.ONTOLOGY_IRI_TERMIT + "/fts/snippet-text")
private String snippetText;

Expand All @@ -80,10 +86,11 @@ public class FullTextSearchResult implements HasIdentifier, HasTypes, Serializab
public FullTextSearchResult() {
}

public FullTextSearchResult(URI uri, String label, URI vocabulary, URI state, String type, String snippetField,
String snippetText, Double score) {
public FullTextSearchResult(URI uri, String label, String description, URI vocabulary, URI state, String type,
String snippetField, String snippetText, Double score) {
this.uri = uri;
this.label = label;
this.description = description;
this.vocabulary = vocabulary;
this.state = state;
this.types = Collections.singleton(type);
Expand All @@ -110,6 +117,14 @@ public void setLabel(String label) {
this.label = label;
}

public String getDescription() {
return description;
}

public void setDescription(String description) {
this.description = description;
}

public URI getVocabulary() {
return vocabulary;
}
Expand Down
13 changes: 12 additions & 1 deletion src/main/resources/query/fulltextsearch.rq
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,26 @@ SELECT ?entity ?label ?vocabularyUri ?state ?type ?snippetField ?snippetText WHE
skos:prefLabel ?label ;
?inVocabulary ?vocabularyUri .
OPTIONAL { ?entity ?hasState ?state . }
OPTIONAL {
?entity skos:definition ?definition .
}
OPTIONAL {
?entity skos:scopeNote ?scopeNote .
}
BIND (?term as ?type) .
} UNION {
?entity a ?vocabulary ;
dc:title ?label .
OPTIONAL {
?entity dc:description ?dcDescription .
}
BIND (?vocabulary as ?type) .
}
BIND (?label as ?snippetText) .
BIND (str("label") as ?snippetField) .
BIND (str("prefLabel") as ?snippetField) .
FILTER CONTAINS(LCASE(?label), LCASE(?searchString)) .
FILTER (lang(?label) = ?langTag)
FILTER NOT EXISTS { ?entity a ?snapshot . }
BIND(COALESCE(?definition, COALESCE(?scopeNote, ?dcDescription)) AS ?description)
FILTER (!BOUND(?description) || lang(?description) = ?langTag)
} ORDER BY ?label
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ void setUp() {
void fullTextSearchExecutesSearchOnService() throws Exception {
final List<FullTextSearchResult> expected = Collections
.singletonList(
new FullTextSearchResult(Generator.generateUri(), "test", null, null, SKOS.CONCEPT,
new FullTextSearchResult(Generator.generateUri(), "test", null, null, null, SKOS.CONCEPT,
"test", "test", 1.0));
when(searchServiceMock.fullTextSearch(any())).thenReturn(expected);
final String searchString = "test";
Expand All @@ -95,7 +95,7 @@ void fullTextSearchExecutesSearchOnService() throws Exception {
void fullTextSearchOfTermsWithoutVocabularySpecificationExecutesSearchOnService() throws Exception {
final URI vocabularyIri = URI.create("https://test.org/vocabulary");
final List<FullTextSearchResult> expected = Collections
.singletonList(new FullTextSearchResult(Generator.generateUri(), "test", vocabularyIri, null,
.singletonList(new FullTextSearchResult(Generator.generateUri(), "test", "Term definition", vocabularyIri, null,
SKOS.CONCEPT, "test", "test", 1.0));
when(searchServiceMock.fullTextSearchOfTerms(any(), any())).thenReturn(expected);
final String searchString = "test";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ void fullTextSearchFiltersResultsFromNonMatchingVocabularies() {
final FullTextSearchResult ftsr = new FullTextSearchResult(
Generator.generateUri(),
"test",
"Term definition",
vocabulary,
null,
SKOS.CONCEPT,
Expand All @@ -88,6 +89,7 @@ void fullTextSearchReturnsResultsFromMatchingVocabularies() {
final FullTextSearchResult ftsr = new FullTextSearchResult(
Generator.generateUri(),
"test",
"Term definition",
vocabulary,
Generator.generateUri(),
SKOS.CONCEPT,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,22 +45,24 @@ class SearchAuthorizationServiceTest {

@Test
void canReadChecksIfVocabularyIsReadableForTermResult() {
final FullTextSearchResult res = new FullTextSearchResult(Generator.generateUri(), "test string",
Generator.generateUri(), Generator.generateUri(),
SKOS.CONCEPT, "label", "test",
(double) Generator.randomInt());
final FullTextSearchResult res = new FullTextSearchResult(Generator.generateUri(), "Term label",
"Term definition",
Generator.generateUri(), Generator.generateUri(),
SKOS.CONCEPT, "label", "test",
(double) Generator.randomInt());
when(vocabularyAuthorizationService.canRead(any(Vocabulary.class))).thenReturn(true);
assertTrue(sut.canRead(res));
verify(vocabularyAuthorizationService).canRead(new Vocabulary(res.getVocabulary()));
}

@Test
void canReadChecksIfVocabularyIsReadableForVocabularyResult() {
final FullTextSearchResult res = new FullTextSearchResult(Generator.generateUri(), "test label",
null, null,
cz.cvut.kbss.termit.util.Vocabulary.s_c_slovnik,
"label", "test",
(double) Generator.randomInt());
final FullTextSearchResult res = new FullTextSearchResult(Generator.generateUri(), "Vocabulary title",
"Vocabulary description",
null, null,
cz.cvut.kbss.termit.util.Vocabulary.s_c_slovnik,
"label", "test",
(double) Generator.randomInt());
assertFalse(sut.canRead(res));
verify(vocabularyAuthorizationService).canRead(new Vocabulary(res.getUri()));
}
Expand Down