Skip to content

Commit

Permalink
fix: update full text querying and totals
Browse files Browse the repository at this point in the history
  • Loading branch information
tpluscode committed Dec 31, 2024
1 parent 8b08425 commit d6ccfe6
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 72 deletions.
8 changes: 5 additions & 3 deletions apis/shared-dimensions/lib/domain/shared-dimensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,11 @@ export async function getSharedTerms<C extends StreamClient | ParsingClient>({ s
}

const { constructQuery } = await shapeToQuery()
return client.query.construct(constructQuery(shape), {
operation: 'postDirect',
}) as any
return {
members: await client.query.construct(constructQuery(shape), {
operation: 'postDirect',
}) as any,
}

Check warning on line 105 in apis/shared-dimensions/lib/domain/shared-dimensions.ts

View check run for this annotation

Codecov / codecov/patch

apis/shared-dimensions/lib/domain/shared-dimensions.ts#L101-L105

Added lines #L101 - L105 were not covered by tests
}

async function loadShape(shape: string, shapeType: NamedNode = sh.NodeShape) {

Check warning on line 108 in apis/shared-dimensions/lib/domain/shared-dimensions.ts

View check run for this annotation

Codecov / codecov/patch

apis/shared-dimensions/lib/domain/shared-dimensions.ts#L108

Added line #L108 was not covered by tests
Expand Down
9 changes: 7 additions & 2 deletions apis/shared-dimensions/lib/handlers/collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { hydra, rdf } from '@tpluscode/rdf-ns-builders'

export interface CollectionData<M extends Stream | Iterable<Quad> = Stream | Iterable<Quad>> {
members: M
totalItems: number
totalItems?: number
}

Check warning on line 10 in apis/shared-dimensions/lib/handlers/collection.ts

View check run for this annotation

Codecov / codecov/patch

apis/shared-dimensions/lib/handlers/collection.ts#L6-L10

Added lines #L6 - L10 were not covered by tests
interface CollectionHandler {
Expand All @@ -25,7 +25,12 @@ export function getCollection({ collection, view, data: { members: memberQuads,
graph.node(collection)
.addOut(rdf.type, [hydra.Collection, collectionType])
.addOut(hydra.member, members)
.addOut(hydra.totalItems, totalItems)

if (totalItems) {
graph.node(collection).addOut(hydra.totalItems, totalItems)
} else {
graph.node(collection).addOut(hydra.totalItems, members.terms.length)
}

Check warning on line 33 in apis/shared-dimensions/lib/handlers/collection.ts

View check run for this annotation

Codecov / codecov/patch

apis/shared-dimensions/lib/handlers/collection.ts#L28-L33

Added lines #L28 - L33 were not covered by tests

if (view) {
graph.node(view)
Expand Down
87 changes: 64 additions & 23 deletions apis/shared-dimensions/lib/shapeToQuery.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import onetime from 'onetime'
import { md } from '@cube-creator/core/namespace'
import { AnyPointer, GraphPointer } from 'clownface'
import clownface, { AnyPointer, GraphPointer } from 'clownface'
import { isGraphPointer } from 'is-graph-pointer'
import { hydra, sh } from '@tpluscode/rdf-ns-builders'
import { Parameters, PropertyShape } from '@hydrofoil/shape-to-query/model/constraint/ConstraintComponent'
import evalTemplateLiteral from 'rdf-loader-code/evalTemplateLiteral.js'
import namespace from '@rdfjs/namespace'
import { sparql } from '@tpluscode/sparql-builder'
import $rdf from 'rdf-ext'
import type { Literal } from '@rdfjs/types'
import type { ServicePattern, GroupPattern } from 'sparqljs'
import env from './env'

/*
Expand All @@ -21,7 +21,11 @@ const _importDynamic = new Function('modulePath', 'return import(modulePath)')
export default async function shapeToQuery(): Promise<Pick<typeof import('@hydrofoil/shape-to-query'), 'constructQuery' | 'deleteQuery' | 's2q'>> {
await setup()

const { constructQuery, deleteQuery, s2q } = await _importDynamic('@hydrofoil/shape-to-query')
const {
constructQuery,
deleteQuery,
s2q,
} = await _importDynamic('@hydrofoil/shape-to-query') as typeof import('@hydrofoil/shape-to-query')

Check warning on line 28 in apis/shared-dimensions/lib/shapeToQuery.ts

View check run for this annotation

Codecov / codecov/patch

apis/shared-dimensions/lib/shapeToQuery.ts#L24-L28

Added lines #L24 - L28 were not covered by tests

return {
constructQuery,
Expand Down Expand Up @@ -76,9 +80,9 @@ const setup = onetime(async () => {
})

async function defineConstraintComponents() {
const { default: ConstraintComponent } = await _importDynamic('@hydrofoil/shape-to-query/model/constraint/ConstraintComponent.js')
const { constraintComponents } = await _importDynamic('@hydrofoil/shape-to-query/model/constraint/index.js')
const { PatternConstraintComponent } = await _importDynamic('@hydrofoil/shape-to-query/model/constraint/pattern.js')
const { default: ConstraintComponent } = await _importDynamic('@hydrofoil/shape-to-query/model/constraint/ConstraintComponent.js') as typeof import('@hydrofoil/shape-to-query/model/constraint/ConstraintComponent.js')
const { constraintComponents } = await _importDynamic('@hydrofoil/shape-to-query/model/constraint/index.js') as typeof import('@hydrofoil/shape-to-query/model/constraint/index.js')
const { PatternConstraintComponent } = await _importDynamic('@hydrofoil/shape-to-query/model/constraint/pattern.js') as typeof import('@hydrofoil/shape-to-query/model/constraint/pattern.js')

Check warning on line 85 in apis/shared-dimensions/lib/shapeToQuery.ts

View check run for this annotation

Codecov / codecov/patch

apis/shared-dimensions/lib/shapeToQuery.ts#L83-L85

Added lines #L83 - L85 were not covered by tests

constraintComponents.set(md.FreeTextSearchConstraintComponent, class TextSearch extends ConstraintComponent {
static match(pointer: GraphPointer) {
Expand All @@ -101,7 +105,7 @@ async function defineConstraintComponents() {
yield new TextSearch('fuseki', patternElement.pointer.value)
break
default:
yield new PatternConstraintComponent('^' + patternElement.pointer.value)
yield new PatternConstraintComponent(patternElement.pointer.term as Literal)

Check warning on line 108 in apis/shared-dimensions/lib/shapeToQuery.ts

View check run for this annotation

Codecov / codecov/patch

apis/shared-dimensions/lib/shapeToQuery.ts#L108

Added line #L108 was not covered by tests
}
}
}
Expand All @@ -110,29 +114,66 @@ async function defineConstraintComponents() {
super(md.FreeTextSearchConstraintComponent)
}

buildPatterns({ focusNode, valueNode, propertyPath }: Parameters): any {
buildPropertyShapePatterns(args: Parameters) {

Check warning on line 117 in apis/shared-dimensions/lib/shapeToQuery.ts

View check run for this annotation

Codecov / codecov/patch

apis/shared-dimensions/lib/shapeToQuery.ts#L117

Added line #L117 was not covered by tests
if (this.vendor === 'stardog') {
const fts = namespace('tag:stardog:api:search:')
return sparql`
service ${fts.textMatch} {
[] ${fts.query} """${this.pattern + '*'}""";
${fts.result} ${valueNode} ;
}
${focusNode} ${propertyPath} ${valueNode} .
`
return [this.stardogServiceGroup(args)]

Check warning on line 119 in apis/shared-dimensions/lib/shapeToQuery.ts

View check run for this annotation

Codecov / codecov/patch

apis/shared-dimensions/lib/shapeToQuery.ts#L119

Added line #L119 was not covered by tests
}

if (this.vendor === 'fuseki') {
return sparql`
${focusNode} <http://jena.apache.org/text#query> (${propertyPath} """${this.pattern + '*'}""") .
# Second filtering to make sure the word starts with the given query
${focusNode} ${propertyPath} ${valueNode} .
FILTER (REGEX(${valueNode}, "^${this.pattern}", "i"))
`
return [this.fusekiPatterns(args)]

Check warning on line 123 in apis/shared-dimensions/lib/shapeToQuery.ts

View check run for this annotation

Codecov / codecov/patch

apis/shared-dimensions/lib/shapeToQuery.ts#L123

Added line #L123 was not covered by tests
}

throw new Error('Unsupported vendor')
}

stardogServiceGroup({ focusNode, valueNode, propertyPath }: Parameters): ServicePattern {
if (!propertyPath || !('value' in propertyPath)) {
throw new Error('Property path must be a named node')
}

const fts = namespace('tag:stardog:api:search:')

const patterns = clownface({ dataset: $rdf.dataset() })
.blankNode()
.addOut(fts.query, $rdf.literal(this.pattern + '*'))
.addOut(fts.result, valueNode)
.node(focusNode).addOut(propertyPath, valueNode)

return {
type: 'service',
name: fts.textMatch,
silent: false,
patterns: [{
type: 'bgp',
triples: [...patterns.dataset],
}],
}
}

fusekiPatterns({ focusNode, valueNode, propertyPath }: Parameters): GroupPattern {
if (!propertyPath || !('value' in propertyPath)) {
throw new Error('Property path must be a named node')
}

const patterns = clownface({ dataset: $rdf.dataset() })
.node(focusNode)
.addList($rdf.namedNode('http://jena.apache.org/text#query'), [propertyPath, $rdf.literal(this.pattern + '*')])
.addOut(propertyPath, valueNode) // Second filtering to make sure the word starts with the given query

return {
type: 'group',
patterns: [{
type: 'bgp',
triples: [...patterns.dataset],
}, {
type: 'filter',
expression: {
type: 'operation',
operator: 'regex',
args: [valueNode, $rdf.literal('^' + this.pattern), $rdf.literal('i')],
},
}],
}
}

Check warning on line 177 in apis/shared-dimensions/lib/shapeToQuery.ts

View check run for this annotation

Codecov / codecov/patch

apis/shared-dimensions/lib/shapeToQuery.ts#L128-L177

Added lines #L128 - L177 were not covered by tests
})
}
2 changes: 1 addition & 1 deletion apis/shared-dimensions/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"@cube-creator/core": "1.0.0",
"@cube-creator/express": "0.0.0",
"@hydrofoil/labyrinth": "^0.4.2",
"@hydrofoil/shape-to-query": "^0.13.4",
"@hydrofoil/shape-to-query": "^0.13.5",
"@rdfine/hydra": "^0.8.2",
"@rdfine/rdfs": "^0.6.4",
"@rdfine/schema": "^0.6.3",
Expand Down
79 changes: 36 additions & 43 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1566,19 +1566,19 @@
rdf-loaders-registry "^0.2.0"
sparql-http-client "^2.2.2"

"@hydrofoil/shape-to-query@^0.13.4":
version "0.13.4"
resolved "https://registry.yarnpkg.com/@hydrofoil/shape-to-query/-/shape-to-query-0.13.4.tgz#61ac73a33a1c8a34f6652a284ec7e2fdf5101b12"
integrity sha512-Q9GDAacePZZQkwnOxOD43BlkWBNDKr+VR05l3B8Q99D9gKYZ5AeF8kNDdH3za9LzES9Hc3hs/g0R8sM0Rz8WiQ==
"@hydrofoil/shape-to-query@^0.13.5":
version "0.13.5"
resolved "https://registry.yarnpkg.com/@hydrofoil/shape-to-query/-/shape-to-query-0.13.5.tgz#246ffcaaf51d1ee3f1f62162310c23a2ad28d7d9"
integrity sha512-bwjUzeOLEV48tldt+0pGH8y21MOTO9cw6A78boM9i+bpKR6UJqAZ6Rv8RmeGSY5GTIILfuelqP/kgOgvM0C6Xw==
dependencies:
"@hydrofoil/sparql-processor" "^0.1.2"
"@hydrofoil/sparql-processor" "^0.1.3"
"@tpluscode/rdf-ns-builders" ">=3.0.2"
"@tpluscode/rdf-string" "^1.3.3"
"@types/sparqljs" "^3.1.11"
"@vocabulary/dash" "^1.0.4"
"@vocabulary/dash-sparql" "^1.0.4"
"@vocabulary/sh" "^1.1.5"
"@zazuko/env" "^2.2.0"
"@zazuko/env" "^2.4.2"
"@zazuko/prefixes" ">=2"
clownface-shacl-path "^2.2"
is-graph-pointer "^2.0.0"
Expand Down Expand Up @@ -1667,10 +1667,10 @@
concat-merge "^1.0.3"
lit "^2.0.0"

"@hydrofoil/sparql-processor@^0.1.2":
version "0.1.2"
resolved "https://registry.yarnpkg.com/@hydrofoil/sparql-processor/-/sparql-processor-0.1.2.tgz#5241204d114c98322a67ffec86fb2398b216586c"
integrity sha512-GjzGkiIA9mjEN8SElcPSfbO43JCpf+tz+r7cErXsb8CtjbP5Lw+/V54jJtu4Y2T0tx5azzXlCwHJC244Svzt5A==
"@hydrofoil/sparql-processor@^0.1.3":
version "0.1.3"
resolved "https://registry.yarnpkg.com/@hydrofoil/sparql-processor/-/sparql-processor-0.1.3.tgz#076b1a5ef53fc9ee65143afbad390b7247531689"
integrity sha512-QVgIy+H3038t0r2EtPuknn1I9Cn2foVKk36uU3Wk+npceFu995kTkH1T77AN4KRxsSZBUyENN9XUxaCvUwiN+Q==
dependencies:
"@types/sparqljs" "^3.1.11"
"@zazuko/prefixes" "^2.1.0"
Expand Down Expand Up @@ -3009,6 +3009,11 @@
dependencies:
xmlchars "^2.2.0"

"@sec-ant/readable-stream@^0.4.1":
version "0.4.1"
resolved "https://registry.yarnpkg.com/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz#60de891bb126abfdc5410fdc6166aca065f10a0c"
integrity sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==

"@sentry/browser@6.17.9":
version "6.17.9"
resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-6.17.9.tgz#62eac0cc3c7c788df6b4677fe9882d3974d84027"
Expand Down Expand Up @@ -4956,10 +4961,10 @@
"@zazuko/env" "^2.1.1"
"@zazuko/rdf-utils-fs" "^3.3.0"

"@zazuko/env@^2.1.1", "@zazuko/env@^2.2.0":
version "2.2.0"
resolved "https://registry.yarnpkg.com/@zazuko/env/-/env-2.2.0.tgz#090ca10466113428483bfffeedf981b0b411d8e5"
integrity sha512-73KwqrckawQTmoPAizlkHIRpsqFOaR31LA4XEZUnLM6CbGF/DhmbclfhMtg8GBAiZLIVdgXj6GZAW0lUmA4knQ==
"@zazuko/env@^2.1.1", "@zazuko/env@^2.4.2":
version "2.4.2"
resolved "https://registry.yarnpkg.com/@zazuko/env/-/env-2.4.2.tgz#a9c3df642e3567f681ad23c3635cafa6bb2fb85d"
integrity sha512-mq3YTIs9dmXh2nyS2Hm94bNRHuItlgrp+5QS1zG6ClSpmgztKhMYNRhssmZvd0kBcpYZSV4+EogI/QxrkCg6ww==
dependencies:
"@rdfjs/data-model" "^2.0.1"
"@rdfjs/dataset" "^2.0.1"
Expand All @@ -4972,7 +4977,7 @@
"@zazuko/env-core" "^1.1.2"
"@zazuko/prefixes" "^2.1.0"
clownface "^2.0.2"
get-stream "^8.0.1"
get-stream "^9.0.1"
rdf-dataset-ext "^1.1.0"

"@zazuko/node-fetch@^2.6.6":
Expand Down Expand Up @@ -8925,6 +8930,14 @@ get-stream@^8.0.1:
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-8.0.1.tgz#def9dfd71742cd7754a7761ed43749a27d02eca2"
integrity sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==

get-stream@^9.0.1:
version "9.0.1"
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-9.0.1.tgz#95157d21df8eb90d1647102b63039b1df60ebd27"
integrity sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==
dependencies:
"@sec-ant/readable-stream" "^0.4.1"
is-stream "^4.0.1"

get-symbol-description@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6"
Expand Down Expand Up @@ -9873,6 +9886,11 @@ is-stream@^3.0.0:
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac"
integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==

is-stream@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-4.0.1.tgz#375cf891e16d2e4baec250b85926cffc14720d9b"
integrity sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==

is-string@^1.0.5, is-string@^1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd"
Expand Down Expand Up @@ -14287,7 +14305,7 @@ string-to-stream@^3.0.1:
dependencies:
readable-stream "^3.4.0"

"string-width-cjs@npm:string-width@^4.2.0":
"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
Expand All @@ -14304,15 +14322,6 @@ string-width@^2.1.1:
is-fullwidth-code-point "^2.0.0"
strip-ansi "^4.0.0"

string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
dependencies:
emoji-regex "^8.0.0"
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1"

string-width@^5.0.0, string-width@^5.0.1, string-width@^5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794"
Expand Down Expand Up @@ -14382,7 +14391,7 @@ string_decoder@~1.1.1:
dependencies:
safe-buffer "~5.1.0"

"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
Expand All @@ -14396,13 +14405,6 @@ strip-ansi@^4.0.0:
dependencies:
ansi-regex "^3.0.0"

strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
dependencies:
ansi-regex "^5.0.1"

strip-ansi@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2"
Expand Down Expand Up @@ -15577,7 +15579,7 @@ workerpool@6.2.1:
resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343"
integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==

"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
Expand All @@ -15603,15 +15605,6 @@ wrap-ansi@^6.2.0:
string-width "^4.1.0"
strip-ansi "^6.0.0"

wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
dependencies:
ansi-styles "^4.0.0"
string-width "^4.1.0"
strip-ansi "^6.0.0"

wrap-ansi@^8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"
Expand Down

0 comments on commit d6ccfe6

Please sign in to comment.