From 983f4b22a3012e540f9527735c36d6d4b4d4ecea Mon Sep 17 00:00:00 2001 From: Vijeinath Tissaveerasingham Date: Tue, 22 Sep 2020 10:19:43 +0200 Subject: [PATCH] Refactoring & Browsing in primary authors --- src/app/search/browsing/browsing.component.ts | 329 ++++++------------ .../services/gravesearch-builder.service.ts | 81 +++++ src/app/services/knora.service.ts | 63 ++++ 3 files changed, 257 insertions(+), 216 deletions(-) diff --git a/src/app/search/browsing/browsing.component.ts b/src/app/search/browsing/browsing.component.ts index 3485dbf2..b3751461 100644 --- a/src/app/search/browsing/browsing.component.ts +++ b/src/app/search/browsing/browsing.component.ts @@ -13,140 +13,6 @@ import {NgxSpinnerService} from "ngx-spinner"; export class BrowsingComponent implements OnInit { @ViewChild("results") resultBox: ResultsComponent; - myAuthor: IMainClass = { - name: "person", - mainClass: {name: "person", variable: "person"}, - props: [ - { - name: "hasFirstName", - priority: 0, - res: null - }, - { - name: "hasLastName", - priority: 0, - res: null - } - ] - }; - myBook: IMainClass = { - name: "passage", - mainClass: {name: "book", variable: "book"}, - props: [ - { - name: "occursIn", - priority: 0, - res: { - name: "book", - props: [ - { - name: "hasBookTitle", - priority: 0, - res: null - }, - { - name: "hasGenre", - priority: 1, - res: null - }, - { - name: "hasCreationDate", - valVar: "creationDate", - priority: 1, - res: null - }, - { - name: "hasPublicationDate", - priority: 1, - res: null - }, - { - name: "hasFirstPerformanceDate", - priority: 1, - res: null - }, - { - name: "hasBookComment", - priority: 1, - res: null - }, - { - name: "isWrittenBy", - priority: 1, - res: { - name: "person", - props: [ - { - name: "hasFirstName", - priority: 0, - res: null - }, - { - name: "hasLastName", - priority: 0, - res: null - } - ] - } - } - ] - } - }, - { - name: "isMentionedIn", - priority: 0, - mandatory: true, - res: { - name: "passage", - props: [ - { - name: "hasText", - valVar: "sText", - priority: 1, - res: null - }, - { - name: "hasDisplayedTitle", - valVar: "sDisplayedTitle", - priority: 1, - res: null - } - ] - } - }, - ] - }; - myLexia: IMainClass = { - name: "lexia", - mainClass: {name: "lexia", variable: "lexia"}, - props: [ - { - name: "hasLexiaInternalId", - priority: 1, - res: null - }, - { - name: "hasLexiaTitle", - priority: 0, - res: null - }, - { - name: "hasLexiaDisplayedTitle", - priority: 1, - res: null - }, - { - name: "hasFormalClass", - priority: 1, - res: null - }, - { - name: "hasImage", - priority: 1, - res: null - } - ] - }; myPassage: IMainClass = { name: "passage", mainClass: {name: "passage", variable: "passage"}, @@ -434,9 +300,6 @@ export class BrowsingComponent implements OnInit { authors = {}; lexias = {}; - authorLastNameRef: IDisplayedProperty; - lexiaTitleRef: IDisplayedProperty; - bookTitleRef: IDisplayedProperty; authorRef: IDisplayedProperty; lexiaRef: IDisplayedProperty; bookRef: IDisplayedProperty; @@ -476,10 +339,7 @@ export class BrowsingComponent implements OnInit { this.lexias[letter] = null; this.chars.push(letter); } - // Preparation for search values - this.authorLastNameRef = this.myAuthor.props[1]; - this.bookTitleRef = this.myBook.props[0].res.props[0]; - this.lexiaTitleRef = this.myLexia.props[1]; + this.authorRef = this.myPassage.props[11].res.props[8]; this.bookRef = this.myPassage.props[11]; this.lexiaRef = this.myPassage.props[14]; @@ -500,62 +360,117 @@ export class BrowsingComponent implements OnInit { size: "small" }); - let cacheStructure: {}; - let structure: IMainClass; - let sort: (a, b) => number; - if (this.resTypeSelected === "author") { - this.authorLastNameRef.searchVal1 = `^${this.charSelected}`; - if (this.bookTitleRef.searchVal1) { - delete this.bookTitleRef.searchVal1; - } - - if (this.lexiaTitleRef.searchVal1) { - delete this.lexiaTitleRef.searchVal1; - } - - cacheStructure = this.authors; - structure = this.myAuthor; - sort = this.sortAuthor; + this.requestAuthors(); } else if (this.resTypeSelected === "book") { - this.bookTitleRef.searchVal1 = `^${this.charSelected}`; - if (this.authorLastNameRef.searchVal1) { - delete this.authorLastNameRef.searchVal1; - } + this.requestBooks(); - if (this.lexiaTitleRef.searchVal1) { - delete this.lexiaTitleRef.searchVal1; - } + } else if (this.resTypeSelected === "lexia") { + + this.requestLexias(); + } + } - cacheStructure = this.books; - structure = this.myBook; - sort = this.sortBook; + requestBooks() { + if (!this.books[this.charSelected]) { + this.knoraService.getPrimaryBooksCount(this.charSelected) + .subscribe(amount => { + console.log(amount); + this.alphabeticResAmount = amount; + this.books[this.charSelected] = {amount}; - } else if (this.resTypeSelected === "lexia") { - this.lexiaTitleRef.searchVal1 = `^${this.charSelected}`; + if (amount === 0) { + this.spinner.hide(`spinner-${this.selectChar}`); + this.alphabeticSearchStarted = false; + return; + } - if (this.bookTitleRef.searchVal1) { - delete this.bookTitleRef.searchVal1; - } + const maxOffset = Math.ceil(this.alphabeticResAmount / 25); + const requests = []; - if (this.authorLastNameRef.searchVal1) { - delete this.authorLastNameRef.searchVal1; - } + for (let offset = 0; offset < maxOffset; offset++) { + requests.push(this.knoraService.getPrimaryBooks(this.charSelected, offset)); + } - cacheStructure = this.lexias; - structure = this.myLexia; - sort = this.sortLexia; + forkJoin(...requests) + .subscribe((res: Array>) => { + this.spinner.hide(`spinner-${this.selectChar}`); + this.alphabeticSearchStarted = false; + this.alphabeticResources = [] + .concat(...res) + .sort((res1, res2) => this.sortBook(res1, res2)); + // Saves data in cache + this.books[this.charSelected].data = this.alphabeticResources; + }, error => { + this.spinner.hide(`spinner-${this.selectChar}`); + }); + }, error => { + this.spinner.hide(`spinner-${this.selectChar}`); + }); + } else { + this.spinner.hide(`spinner-${this.selectChar}`); + this.alphabeticSearchStarted = false; + // Gets data from cache + this.alphabeticResources = this.books[this.charSelected].data; + this.alphabeticResAmount = this.books[this.charSelected].amount; } + } + + requestAuthors() { + if (!this.authors[this.charSelected]) { + this.knoraService.getPrimaryAuthorsCount(this.charSelected) + .subscribe(amount => { + console.log(amount); + this.alphabeticResAmount = amount; + this.authors[this.charSelected] = {amount}; + + if (amount === 0) { + this.spinner.hide(`spinner-${this.selectChar}`); + this.alphabeticSearchStarted = false; + return; + } - if (!cacheStructure[this.charSelected]) { + const maxOffset = Math.ceil(this.alphabeticResAmount / 25); + const requests = []; - this.knoraService.graveSearchQueryCount(structure, this.priority) + for (let offset = 0; offset < maxOffset; offset++) { + requests.push(this.knoraService.getPrimaryAuthors(this.charSelected, offset)); + } + + forkJoin(...requests) + .subscribe((res: Array>) => { + this.spinner.hide(`spinner-${this.selectChar}`); + this.alphabeticSearchStarted = false; + this.alphabeticResources = [] + .concat(...res) + .sort((res1, res2) => this.sortAuthor(res1, res2)); + // Saves data in cache + this.authors[this.charSelected].data = this.alphabeticResources; + }, error => { + this.spinner.hide(`spinner-${this.selectChar}`); + }); + }, error => { + this.spinner.hide(`spinner-${this.selectChar}`); + }); + } else { + this.spinner.hide(`spinner-${this.selectChar}`); + this.alphabeticSearchStarted = false; + // Gets data from cache + this.alphabeticResources = this.authors[this.charSelected].data; + this.alphabeticResAmount = this.authors[this.charSelected].amount; + } + } + + requestLexias() { + if (!this.lexias[this.charSelected]) { + this.knoraService.getLexiasCount(this.charSelected) .subscribe(amount => { + console.log(amount); this.alphabeticResAmount = amount; - cacheStructure[this.charSelected] = {amount}; + this.lexias[this.charSelected] = {amount}; if (amount === 0) { this.spinner.hide(`spinner-${this.selectChar}`); @@ -567,7 +482,7 @@ export class BrowsingComponent implements OnInit { const requests = []; for (let offset = 0; offset < maxOffset; offset++) { - requests.push(this.knoraService.graveSeachQuery(structure, this.priority, offset)); + requests.push(this.knoraService.getLexias(this.charSelected, offset)); } forkJoin(...requests) @@ -576,17 +491,21 @@ export class BrowsingComponent implements OnInit { this.alphabeticSearchStarted = false; this.alphabeticResources = [] .concat(...res) - .sort((res1, res2) => sort(res1, res2)); + .sort((res1, res2) => this.sortLexia(res1, res2)); // Saves data in cache - cacheStructure[this.charSelected].data = this.alphabeticResources; + this.lexias[this.charSelected].data = this.alphabeticResources; + }, error => { + this.spinner.hide(`spinner-${this.selectChar}`); }); + }, error => { + this.spinner.hide(`spinner-${this.selectChar}`); }); } else { this.spinner.hide(`spinner-${this.selectChar}`); this.alphabeticSearchStarted = false; // Gets data from cache - this.alphabeticResources = cacheStructure[this.charSelected].data; - this.alphabeticResAmount = cacheStructure[this.charSelected].amount; + this.alphabeticResources = this.lexias[this.charSelected].data; + this.alphabeticResAmount = this.lexias[this.charSelected].amount; } } @@ -646,46 +565,24 @@ export class BrowsingComponent implements OnInit { } detailSelected(res: any) { - console.log("detail", res); if (this.resTypeSelected === "author") { this.authorRef.searchVal1 = res.id; - - if (this.bookRef.searchVal1) { - delete this.bookRef.searchVal1; - } - - if (this.lexiaRef.searchVal1) { - delete this.lexiaRef.searchVal1; - } - - this.resultBox.search(this.myPassage); + this.bookRef.searchVal1 = null; + this.lexiaRef.searchVal1 = null; } else if (this.resTypeSelected === "book") { this.bookRef.searchVal1 = res.id; - - if (this.authorRef.searchVal1) { - delete this.authorRef.searchVal1; - } - - if (this.lexiaRef.searchVal1) { - delete this.lexiaRef.searchVal1; - } - - this.resultBox.search(this.myPassage); + this.authorRef.searchVal1 = null; + this.lexiaRef.searchVal1 = null; } else if (this.resTypeSelected === "lexia") { this.lexiaRef.searchVal1 = res.id; + this.bookRef.searchVal1 = null; + this.authorRef.searchVal1 = null; - if (this.bookRef.searchVal1) { - delete this.bookRef.searchVal1; - } - - if (this.authorRef.searchVal1) { - delete this.authorRef.searchVal1; - } - - this.resultBox.search(this.myPassage); } + + this.resultBox.search(this.myPassage); } } diff --git a/src/app/services/gravesearch-builder.service.ts b/src/app/services/gravesearch-builder.service.ts index a468b4f5..bb25ecbd 100644 --- a/src/app/services/gravesearch-builder.service.ts +++ b/src/app/services/gravesearch-builder.service.ts @@ -517,4 +517,85 @@ export class GravesearchBuilderService { getQuery(structure: IMainClass, priority: number, offset?: number): string { return this.getMainQuery(structure, priority, offset); } + + getPrimaryAuthorsQuery(char: string, offset?: number): string { + const node: IMainClassObject = {name: "person", variable: "person"}; + const query = [ + "PREFIX knora-api: ", + "PREFIX knora-api-simple: ", + `PREFIX teimww: <${this.host}/ontology/0826/teimww/v2#>`, + "", + "CONSTRUCT {", + `${this.getFirstConstructLine(node).join("")}`, + "?book teimww:isWrittenBy ?person .", + "?passage teimww:occursIn ?book .", + "?passage teimww:isMentionedIn ?sPassage .", + "?person teimww:hasFirstName ?firstName .", + "?person teimww:hasLastName ?lastName .", + "} WHERE {", + `${this.getFirstWhereLine(node).join("")}`, + "?person teimww:hasLastName ?lastName .", + "?lastName knora-api:valueAsString ?lastNameString .", + `FILTER regex(?lastNameString, \"^${char}\", \"i\")`, + "OPTIONAL { ?person teimww:hasFirstName ?firstName . }", + "?book teimww:isWrittenBy ?person .", + "?passage teimww:occursIn ?book .", + "?passage teimww:isMentionedIn ?sPassage .", + "", + "}", + "", + `OFFSET ${offset ? offset : 0}` + ]; + return query.join("\n"); + } + + getPrimaryBooksQuery(char: string, offset?: number): string { + const node: IMainClassObject = {name: "book", variable: "book"}; + const query = [ + "PREFIX knora-api: ", + "PREFIX knora-api-simple: ", + `PREFIX teimww: <${this.host}/ontology/0826/teimww/v2#>`, + "", + "CONSTRUCT {", + `${this.getFirstConstructLine(node).join("")}`, + "?book teimww:hasBookTitle ?bookTitle .", + "?passage teimww:occursIn ?book .", + "?passage teimww:isMentionedIn ?sPassage .", + "} WHERE {", + `${this.getFirstWhereLine(node).join("")}`, + "?book teimww:hasBookTitle ?bookTitle .", + "?bookTitle knora-api:valueAsString ?bookTitleString .", + `FILTER regex(?bookTitleString, \"^${char}\", \"i\")`, + "?passage teimww:occursIn ?book .", + "?passage teimww:isMentionedIn ?sPassage .", + "", + "}", + "", + `OFFSET ${offset ? offset : 0}` + ]; + return query.join("\n"); + } + + getLexiasQuery(char: string, offset?: number): string { + const node: IMainClassObject = {name: "lexia", variable: "lexia"}; + const query = [ + "PREFIX knora-api: ", + "PREFIX knora-api-simple: ", + `PREFIX teimww: <${this.host}/ontology/0826/teimww/v2#>`, + "", + "CONSTRUCT {", + `${this.getFirstConstructLine(node).join("")}`, + "?lexia teimww:hasLexiaTitle ?lexiaTitle .", + "} WHERE {", + `${this.getFirstWhereLine(node).join("")}`, + "?lexia teimww:hasLexiaTitle ?lexiaTitle .", + "?lexiaTitle knora-api:valueAsString ?lexiaTitleString .", + `FILTER regex(?lexiaTitleString, \"^${char}\", \"i\")`, + "", + "}", + "", + `OFFSET ${offset ? offset : 0}` + ]; + return query.join("\n"); + } } diff --git a/src/app/services/knora.service.ts b/src/app/services/knora.service.ts index 1f091076..c99280a3 100644 --- a/src/app/services/knora.service.ts +++ b/src/app/services/knora.service.ts @@ -139,6 +139,69 @@ export class KnoraService { .pipe(map((res: ReadResource) => this.processRes(res))); } + getPrimaryAuthorsCount(char: string, offset?: number) { + const graveSearch = this.gsBuilder.getPrimaryAuthorsQuery(char, offset); + console.log(graveSearch); + return this.knoraApiConnection.v2.search.doExtendedSearchCountQuery(graveSearch) + .pipe( + map((data: CountQueryResponse) => data.numberOfResults) + ); + } + + getPrimaryAuthors(char: string, offset?: number) { + const graveSearch = this.gsBuilder.getPrimaryAuthorsQuery(char, offset); + console.log(graveSearch); + return this.knoraApiConnection.v2.search.doExtendedSearch(graveSearch) + .pipe( + tap(data => console.log(data)), + map((sequence: ReadResourceSequence) => { + return sequence.resources.map(resource => this.processRes(resource)); + }) + ); + } + + getPrimaryBooksCount(char: string, offset?: number) { + const graveSearch = this.gsBuilder.getPrimaryBooksQuery(char, offset); + console.log(graveSearch); + return this.knoraApiConnection.v2.search.doExtendedSearchCountQuery(graveSearch) + .pipe( + map((data: CountQueryResponse) => data.numberOfResults) + ); + } + + getPrimaryBooks(char: string, offset?: number) { + const graveSearch = this.gsBuilder.getPrimaryBooksQuery(char, offset); + console.log(graveSearch); + return this.knoraApiConnection.v2.search.doExtendedSearch(graveSearch) + .pipe( + tap(data => console.log(data)), + map((sequence: ReadResourceSequence) => { + return sequence.resources.map(resource => this.processRes(resource)); + }) + ); + } + + getLexiasCount(char: string, offset?: number) { + const graveSearch = this.gsBuilder.getLexiasQuery(char, offset); + console.log(graveSearch); + return this.knoraApiConnection.v2.search.doExtendedSearchCountQuery(graveSearch) + .pipe( + map((data: CountQueryResponse) => data.numberOfResults) + ); + } + + getLexias(char: string, offset?: number) { + const graveSearch = this.gsBuilder.getLexiasQuery(char, offset); + console.log(graveSearch); + return this.knoraApiConnection.v2.search.doExtendedSearch(graveSearch) + .pipe( + tap(data => console.log(data)), + map((sequence: ReadResourceSequence) => { + return sequence.resources.map(resource => this.processRes(resource)); + }) + ); + } + // Empty methods for future // getProjectOntology() {} // getNodeOfList(iri: string) {}