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

Implement search endpoint. #116

Merged
merged 6 commits into from
Apr 30, 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
20 changes: 19 additions & 1 deletion src/backend/animaltroove/pom.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
Expand Down Expand Up @@ -35,6 +35,24 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Apache Jena Core -->
<dependency>
<groupId>org.apache.jena</groupId>
<artifactId>jena-arq</artifactId>
<version>4.9.0</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.apache.jena</groupId>
<artifactId>jena-core</artifactId>
<version>4.6.0</version>
</dependency>
<dependency>
<groupId>org.apache.jena</groupId>
<artifactId>apache-jena-libs</artifactId>
<type>pom</type>
<version>4.6.0</version>
</dependency>
</dependencies>
<build>
<plugins>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.bounswe2024group10.animaltroove.controller;

import com.bounswe2024group10.animaltroove.service.SearchService;
import com.bounswe2024group10.animaltroove.dto.SearchRequest;
import com.bounswe2024group10.animaltroove.dto.SearchResponse;

import org.apache.jena.base.Sys;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
public class SearchController {

@Autowired
private SearchService searchService;

@PostMapping("/search")
public ResponseEntity<SearchResponse> search(@RequestBody SearchRequest searchRequest) {
SearchResponse searchResponse = searchService.search(searchRequest.getSearchTerm());
if (searchResponse == null) {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
return new ResponseEntity<>(searchResponse, HttpStatus.OK);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.bounswe2024group10.animaltroove.dto;

public class SearchRequest {
private String searchTerm;

public SearchRequest() {
// Default constructor
}

public SearchRequest(String searchTerm) {
this.searchTerm = searchTerm;
}

public String getSearchTerm() {
return searchTerm;
}

public void setSearchTerm(String searchTerm) {
this.searchTerm = searchTerm;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package com.bounswe2024group10.animaltroove.dto;

public class SearchResponse {
private String name;
private String cycle;
private String pregnancy;
private String lifeExpectancy;
private String heartRate;
private String speed;
private String numberOfBirths;
private String pic;
private String wingSpan;
private String conservationStatus;
private String mainLabel;

public SearchResponse() {
// Default constructor
}

// Getters and setters for each field
public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getCycle() {
return cycle;
}

public void setMainLabel(String mainLabel) {
this.mainLabel = mainLabel;
}
public String getMainLabel() {
return this.mainLabel;
}

public void setCycle(String cycle) {
this.cycle = cycle;
}
public void setPic(String pic){this.pic = pic;}

public String getPic(){return this.pic;}
public String getPregnancy() {
return pregnancy;
}

public void setPregnancy(String pregnancy) {
this.pregnancy = pregnancy;
}

public String getLifeExpectancy() {
return lifeExpectancy;
}

public void setLifeExpectancy(String lifeExpectancy) {
this.lifeExpectancy = lifeExpectancy;
}

public String getHeartRate() {
return heartRate;
}

public void setHeartRate(String heartRate) {
this.heartRate = heartRate;
}

public String getSpeed() {
return speed;
}

public void setSpeed(String speed) {
this.speed = speed;
}

public String getNumberOfBirths() {
return numberOfBirths;
}

public void setNumberOfBirths(String numberOfBirths) {
this.numberOfBirths = numberOfBirths;
}

public String getWingSpan() {
return wingSpan;
}

public void setWingSpan(String wingSpan) {
this.wingSpan = wingSpan;
}

public String getConservationStatus() {
return conservationStatus;
}

public void setConservationStatus(String conservationStatus) {
this.conservationStatus = conservationStatus;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
package com.bounswe2024group10.animaltroove.service;

import com.bounswe2024group10.animaltroove.dto.SearchResponse;

import java.util.List;

import org.apache.jena.query.*;
import org.springframework.stereotype.Service;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;
import org.apache.jena.util.FileManager;

@Service
public class SearchService {

public SearchResponse search(String searchTerm) {
String entityURI = getEntityURI(searchTerm);
System.out.println("Entity URI" +entityURI);
if (entityURI == null) {
return null;
}
SearchResponse searchResponse = getAnimalDetails(entityURI);
System.out.println(searchResponse.toString());
return searchResponse;
}

public String getEntityURI(String searchTerm) {
String sparqlEndpoint = "https://query.wikidata.org/sparql";
String queryString = "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\n" +
"PREFIX wdt: <http://www.wikidata.org/prop/direct/>\n" +
"PREFIX wd: <http://www.wikidata.org/entity/>\n" +
"SELECT ?entity\n" +
"WHERE {\n" +
"?entity rdfs:label \"" + searchTerm + "\"@en.\n" +

"?entity wdt:P31 wd:Q16521\n" +
"}";



String qStringTest = "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\n" +
" PREFIX wdt: <http://www.wikidata.org/prop/direct/>\n" +
" PREFIX wd: <http://www.wikidata.org/entity/>\n" +
"PREFIX wikibase: <http://wikiba.se/ontology#>\n" +
"PREFIX skos: <http://www.w3.org/2004/02/skos/core#>\n" +
"SELECT ?entity\n" +
"WHERE {\n" +
" ?entity skos:altLabel ?alias .\n" +
" FILTER(CONTAINS(LCASE(?alias), \" "+searchTerm.toLowerCase() + "\"))\n" +
// " {\n" +
// " ?entity wdt:P31 wd:Q16521 .\n" +
// " }\n" +
// " UNION\n" +
" {\n" +
" ?entity wdt:P279* wd:Q729 .\n" +
" }\n" +
// " SERVICE wikibase:label { bd:serviceParam wikibase:language \"en\". }\n" +
"}\n" +
"LIMIT 10";
Query query1 = QueryFactory.create(qStringTest);
QueryExecution qexec = QueryExecutionFactory.sparqlService(sparqlEndpoint,query1);
ResultSet resultSet = qexec.execSelect();
System.out.println("REsult rows" + resultSet.getRowNumber());
if (resultSet.hasNext()) {
QuerySolution querySolution = resultSet.next();
if (querySolution.get("entity") != null) {
System.out.println("WE HAVE ENTITY");
return querySolution.get("entity").toString().split("/")[4];
}
}
return null;
}

SearchResponse getAnimalDetails(String entityURI) {
System.out.println("Entitiy URI is : "+ entityURI);
String sparqlEndpoint = "https://query.wikidata.org/sparql";
String queryString = "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\n" +
"PREFIX wdt: <http://www.wikidata.org/prop/direct/>\n" +
"PREFIX wd: <http://www.wikidata.org/entity/>\n" +
"PREFIX wikibase: <http://wikiba.se/ontology#>\n" +
"PREFIX bd: <http://www.bigdata.com/rdf#>\n" +
"SELECT ?itemLabel ?picLabel ?nameLabel ?cycleLabel ?pregLabel ?lifeLabel ?heartLabel ?speedLabel ?numBirthLabel ?wingSpanLabel ?conservationStatLabel\n" +
"WHERE {\n" +
" wd:" + entityURI + " rdfs:label ?itemLabel .\n" + // Fetch the label of the main item
" FILTER(LANG(?itemLabel) = \"en\")\n" + // Ensure the label is in English
" OPTIONAL {wd:" + entityURI + " wdt:P18 ?pic.}\n" +
" OPTIONAL {wd:" + entityURI + " wdt:P225 ?name.}\n" +
" OPTIONAL {wd:" + entityURI + " wdt:P9566 ?cycle.}\n" +
" OPTIONAL {wd:" + entityURI + " wdt:P3063 ?preg.}\n" +
" OPTIONAL {wd:" + entityURI + " wdt:P2250 ?life.}\n" +
" OPTIONAL {wd:" + entityURI + " wdt:P3395 ?heart.}\n" +
" OPTIONAL {wd:" + entityURI + " wdt:P2052 ?speed.}\n" +
" OPTIONAL {wd:" + entityURI + " wdt:P7725 ?numBirth.}\n" +
" OPTIONAL {wd:" + entityURI + " wdt:P2050 ?wingSpan.}\n" +
" OPTIONAL {wd:" + entityURI + " wdt:P141 ?conservationStat.}\n" +
" SERVICE wikibase:label { bd:serviceParam wikibase:language \"en\". }\n" +
"}";
Query query2 = QueryFactory.create(queryString);
QueryExecution queryExec = QueryExecutionFactory.sparqlService(sparqlEndpoint,query2);
ResultSet resultSet = queryExec.execSelect();

if (resultSet.hasNext()) {
QuerySolution querySolution = resultSet.next();
SearchResponse searchResponse = new SearchResponse();
if (querySolution.get("nameLabel") != null) {
searchResponse.setName(querySolution.get("nameLabel").toString());
}
if (querySolution.get("cycleLabel") != null) {
String cycleLabel = querySolution.get("cycleLabel").toString();
if (cycleLabel.contains("@en")) {
cycleLabel = cycleLabel.substring(0, cycleLabel.indexOf("@en"));
}
searchResponse.setCycle(cycleLabel);
}
if (querySolution.get("itemLabel") != null) {
String itemLabel = querySolution.get("itemLabel").toString();
if (itemLabel.contains("@en")) {
itemLabel = itemLabel.substring(0, itemLabel.indexOf("@en"));
}
searchResponse.setMainLabel(itemLabel);
}
if (querySolution.get("pregLabel") != null) {
searchResponse.setPregnancy(querySolution.get("pregLabel").toString());
}
if (querySolution.get("lifeLabel") != null) {
searchResponse.setLifeExpectancy(querySolution.get("lifeLabel").toString());
}
if (querySolution.get("heartLabel") != null) {
searchResponse.setHeartRate(querySolution.get("heartLabel").toString());
}
if (querySolution.get("speedLabel") != null) {
searchResponse.setSpeed(querySolution.get("speedLabel").toString());
}
if (querySolution.get("numBirthLabel") != null) {
searchResponse.setNumberOfBirths(querySolution.get("numBirthLabel").toString());
}
if(querySolution.get("picLabel")!=null){
searchResponse.setPic(querySolution.get("picLabel").toString());
}
if (querySolution.get("wingSpanLabel") != null) {
searchResponse.setWingSpan(querySolution.get("wingSpanLabel").toString());
}
if (querySolution.get("conservationStatLabel") != null) {
String conservationStatLabel = querySolution.get("conservationStatLabel").toString();
if (conservationStatLabel.contains("@en")) {
conservationStatLabel = conservationStatLabel.substring(0, conservationStatLabel.indexOf("@en"));
}
searchResponse.setConservationStatus(conservationStatLabel);

}
return searchResponse;
}
return null;
}
}