ochre-sdk 1.0.78 → 1.0.79

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/query.d.mts CHANGED
@@ -8,9 +8,12 @@ export declare function buildBelongsToCollectionQueryExpression(belongsToCollect
8
8
  * Most queries compile to a single `cts:search` over the Set item projections.
9
9
  * An `ocr` leaf cannot: the projections drop the `<ocr>` layer, so it resolves
10
10
  * to a search over the Resource documents whose matching UUIDs are joined back
11
- * in as an item path predicate. Path predicates only ever AND, so an `ocr` leaf
12
- * that sits under an `or` becomes its own arm of a node union instead, and one
13
- * that sits under an `and` alongside a union becomes an intersection.
11
+ * in as an item path predicate. A negated leaf cannot either, because CTS
12
+ * answers a negation for the whole fragment rather than for the item that
13
+ * matched, so it is filtered per item instead. Path predicates only ever AND,
14
+ * so such a leaf that sits under an `or` becomes its own arm of a node union
15
+ * instead, and one that sits under an `and` alongside a union becomes an
16
+ * intersection.
14
17
  *
15
18
  * The searchable path has to stay inline in `cts:search`: binding it to a
16
19
  * variable first makes every query XDMP-UNSEARCHABLE.
package/dist/query.mjs CHANGED
@@ -940,6 +940,23 @@ function buildCtsItemsPlan(queryExpression) {
940
940
  };
941
941
  }
942
942
  /**
943
+ * Plan a negated leaf as an item path predicate
944
+ *
945
+ * A Set holds every one of its items in one fragment, and CTS resolves
946
+ * `cts:not-query` from the fragment indexes without filtering the match down to
947
+ * the node it came from. Negating inside the search query would therefore drop
948
+ * every item of a Set as soon as one of them matched, and keep every item of a
949
+ * Set that held no match at all. `cts:contains` evaluates the leaf against one
950
+ * item projection instead, which is the scope the negation is asking about.
951
+ */
952
+ function buildNegatedItemsPlan(queryExpression) {
953
+ return {
954
+ kind: "search",
955
+ itemPredicates: [`[not(cts:contains(., ${queryExpression}))]`],
956
+ queryExpressions: []
957
+ };
958
+ }
959
+ /**
943
960
  * Splice the children of same-kind child plans into their parent, so that a
944
961
  * nested group of the same operator does not cost an extra search
945
962
  */
@@ -1021,7 +1038,7 @@ function buildItemsPlan(context, query) {
1021
1038
  };
1022
1039
  }
1023
1040
  const queryExpression = buildLeafQueryExpression(context, query);
1024
- return buildCtsItemsPlan(query.isNegated === true ? buildNotCtsQueryExpression(queryExpression) : queryExpression);
1041
+ return query.isNegated === true ? buildNegatedItemsPlan(queryExpression) : buildCtsItemsPlan(queryExpression);
1025
1042
  }
1026
1043
  const optimizedIncludesGroupQueries = getCompatibleIncludesGroupLeaves(query);
1027
1044
  if (optimizedIncludesGroupQueries != null) return buildCtsItemsPlan(buildIncludesGroupQueryExpression(context, optimizedIncludesGroupQueries));
@@ -1066,9 +1083,12 @@ function buildBelongsToCollectionQueryExpression(belongsToCollectionScopeUuids,
1066
1083
  * Most queries compile to a single `cts:search` over the Set item projections.
1067
1084
  * An `ocr` leaf cannot: the projections drop the `<ocr>` layer, so it resolves
1068
1085
  * to a search over the Resource documents whose matching UUIDs are joined back
1069
- * in as an item path predicate. Path predicates only ever AND, so an `ocr` leaf
1070
- * that sits under an `or` becomes its own arm of a node union instead, and one
1071
- * that sits under an `and` alongside a union becomes an intersection.
1086
+ * in as an item path predicate. A negated leaf cannot either, because CTS
1087
+ * answers a negation for the whole fragment rather than for the item that
1088
+ * matched, so it is filtered per item instead. Path predicates only ever AND,
1089
+ * so such a leaf that sits under an `or` becomes its own arm of a node union
1090
+ * instead, and one that sits under an `and` alongside a union becomes an
1091
+ * intersection.
1072
1092
  *
1073
1093
  * The searchable path has to stay inline in `cts:search`: binding it to a
1074
1094
  * variable first makes every query XDMP-UNSEARCHABLE.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ochre-sdk",
3
- "version": "1.0.78",
3
+ "version": "1.0.79",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "Node.js library for working with OCHRE (Online Cultural and Historical Research Environment) data",