@lde/pipeline-void 0.37.0 → 0.37.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/stage.js +1 -1
- package/package.json +3 -3
- package/queries/object-literals.rq +9 -4
- package/queries/object-uris.rq +9 -4
- package/queries/subject-uri-space.rq +27 -18
- package/queries/subjects.rq +9 -4
package/dist/stage.js
CHANGED
|
@@ -119,7 +119,7 @@ export function subjectUriSpaces(options) {
|
|
|
119
119
|
export function classPartitions(options) {
|
|
120
120
|
return createVoidStage(VOID_STAGE_NAMES.classPartitions, options);
|
|
121
121
|
}
|
|
122
|
-
// Scalar-aggregate counts: each query
|
|
122
|
+
// Scalar-aggregate counts: each query ends in one COUNT without GROUP BY/HAVING,
|
|
123
123
|
// so it always returns exactly one row. Zero output therefore means the endpoint
|
|
124
124
|
// truncated the response, so they set `expectsOutput` to fail (and trigger the
|
|
125
125
|
// reactive dump fallback) rather than store a missing count.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lde/pipeline-void",
|
|
3
|
-
"version": "0.37.
|
|
3
|
+
"version": "0.37.1",
|
|
4
4
|
"description": "VOiD (Vocabulary of Interlinked Datasets) statistical analysis for RDF datasets",
|
|
5
5
|
"repository": {
|
|
6
6
|
"url": "git+https://github.com/ldelements/lde.git",
|
|
@@ -29,11 +29,11 @@
|
|
|
29
29
|
"@rdfjs/types": "^2.0.1",
|
|
30
30
|
"@tpluscode/rdf-ns-builders": "^5.0.0",
|
|
31
31
|
"@zazuko/prefixes": "^2.6.1",
|
|
32
|
-
"n3": "^2.
|
|
32
|
+
"n3": "^2.13.12",
|
|
33
33
|
"tslib": "^2.3.0"
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
|
36
36
|
"@lde/dataset": "^0.8.0",
|
|
37
|
-
"@lde/pipeline": "^0.38.
|
|
37
|
+
"@lde/pipeline": "^0.38.1"
|
|
38
38
|
}
|
|
39
39
|
}
|
|
@@ -6,9 +6,14 @@ CONSTRUCT {
|
|
|
6
6
|
void-ext:distinctLiterals ?distinctLiterals .
|
|
7
7
|
}
|
|
8
8
|
WHERE {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
# Count groups instead of COUNT(DISTINCT): QLever then needs far less memory,
|
|
10
|
+
# and Fuseki and Virtuoso are as fast. A DISTINCT subquery ran Fuseki out of memory.
|
|
11
|
+
SELECT (COUNT(*) AS ?distinctLiterals) {
|
|
12
|
+
SELECT ?o {
|
|
13
|
+
#subjectFilter#
|
|
14
|
+
?s ?p ?o .
|
|
15
|
+
FILTER(ISLITERAL(?o))
|
|
16
|
+
}
|
|
17
|
+
GROUP BY ?o
|
|
13
18
|
}
|
|
14
19
|
}
|
package/queries/object-uris.rq
CHANGED
|
@@ -6,9 +6,14 @@ CONSTRUCT {
|
|
|
6
6
|
void-ext:distinctIRIReferenceObjects ?distinctIRIReferenceObjects .
|
|
7
7
|
}
|
|
8
8
|
WHERE {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
# Count groups instead of COUNT(DISTINCT): QLever then needs far less memory,
|
|
10
|
+
# and Fuseki and Virtuoso are as fast.
|
|
11
|
+
SELECT (COUNT(*) AS ?distinctIRIReferenceObjects) {
|
|
12
|
+
SELECT ?o {
|
|
13
|
+
#subjectFilter#
|
|
14
|
+
?s ?p ?o .
|
|
15
|
+
FILTER(ISIRI(?o))
|
|
16
|
+
}
|
|
17
|
+
GROUP BY ?o
|
|
13
18
|
}
|
|
14
19
|
}
|
|
@@ -10,31 +10,41 @@ WHERE {
|
|
|
10
10
|
{
|
|
11
11
|
SELECT ?uriSpace (SUM(?groupCount) AS ?count) {
|
|
12
12
|
{
|
|
13
|
-
# Group
|
|
14
|
-
#
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
(MIN(?document) AS ?firstDocument) (MAX(?document) AS ?lastDocument) {
|
|
13
|
+
# Group the keys by directory, keeping hash IRIs apart. The number of keys in a
|
|
14
|
+
# hash group is the number of documents it holds.
|
|
15
|
+
SELECT ?directory ?isHash (SUM(?keyCount) AS ?groupCount)
|
|
16
|
+
(COUNT(*) AS ?documents) (MIN(?key) AS ?firstKey) {
|
|
18
17
|
{
|
|
19
|
-
#
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
# Reduce each distinct subject to one key with a single REPLACE: its
|
|
19
|
+
# document followed by "#" for a hash IRI, its directory otherwise.
|
|
20
|
+
# Grouping on that key first keeps the per-subject strings to one. The
|
|
21
|
+
# pattern uses + rather than *, because Virtuoso rejects a pattern that
|
|
22
|
+
# matches the empty string; an IRI ending in / is its own key either way.
|
|
23
|
+
SELECT ?key (COUNT(*) AS ?keyCount) {
|
|
24
|
+
{
|
|
25
|
+
SELECT DISTINCT ?s {
|
|
26
|
+
#subjectFilter#
|
|
27
|
+
?s ?p ?o .
|
|
28
|
+
FILTER(ISIRI(?s))
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
BIND(REPLACE(STR(?s), "(#).*$|[^/#]+$", "$1") AS ?key)
|
|
24
32
|
}
|
|
33
|
+
GROUP BY ?key
|
|
25
34
|
}
|
|
26
|
-
BIND(
|
|
27
|
-
BIND(
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
35
|
+
BIND(STRENDS(?key, "#") AS ?isHash)
|
|
36
|
+
BIND(IF(?isHash, REPLACE(?key, "[^/]*#$", ""), ?key) AS ?prefix)
|
|
37
|
+
# A subject without hash and without path (http://host, urn:…) is a URI
|
|
38
|
+
# space of its own with one entity, which the count filter below drops.
|
|
39
|
+
FILTER(?isHash || (?prefix != "" && !STRENDS(?prefix, "//")))
|
|
40
|
+
# A hash document without path is its own directory.
|
|
41
|
+
BIND(IF(?prefix = "" || STRENDS(?prefix, "//"), STRBEFORE(?key, "#"), ?prefix) AS ?directory)
|
|
32
42
|
}
|
|
33
43
|
GROUP BY ?directory ?isHash
|
|
34
44
|
}
|
|
35
45
|
# A hash vocabulary (…/skos/core#) keeps its document as namespace; hash IRIs spread
|
|
36
46
|
# over several documents (…/record1#media, …/record2#media) share their directory.
|
|
37
|
-
BIND(IF(?isHash && ?
|
|
47
|
+
BIND(IF(?isHash && ?documents = 1, ?firstKey, ?directory) AS ?uriSpace)
|
|
38
48
|
}
|
|
39
49
|
GROUP BY ?uriSpace
|
|
40
50
|
ORDER BY DESC(?count)
|
|
@@ -43,4 +53,3 @@ WHERE {
|
|
|
43
53
|
FILTER(?count > 1) # Only include namespaces with more than 1 entity
|
|
44
54
|
BIND(URI(CONCAT(STR(?dataset), "/.well-known/void#subject-uri-space-", MD5(?uriSpace))) AS ?subset)
|
|
45
55
|
}
|
|
46
|
-
|
package/queries/subjects.rq
CHANGED
|
@@ -5,9 +5,14 @@ CONSTRUCT {
|
|
|
5
5
|
void:distinctSubjects ?count .
|
|
6
6
|
}
|
|
7
7
|
WHERE {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
# Count groups instead of COUNT(DISTINCT): QLever then needs far less memory,
|
|
9
|
+
# Virtuoso half the time, and Fuseki is as fast.
|
|
10
|
+
SELECT (COUNT(*) AS ?count) {
|
|
11
|
+
SELECT ?s {
|
|
12
|
+
#subjectFilter#
|
|
13
|
+
?s ?p ?o .
|
|
14
|
+
FILTER(!ISBLANK(?s))
|
|
15
|
+
}
|
|
16
|
+
GROUP BY ?s
|
|
12
17
|
}
|
|
13
18
|
}
|