graphile-search 1.5.6 → 1.5.7
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/esm/plugin.js +42 -21
- package/package.json +2 -2
- package/plugin.js +42 -21
package/esm/plugin.js
CHANGED
|
@@ -104,6 +104,13 @@ export function createUnifiedSearchPlugin(options) {
|
|
|
104
104
|
const { adapters, enableSearchScore = true, enableFullTextSearch = true } = options;
|
|
105
105
|
// Per-codec cache of discovered columns, keyed by codec name
|
|
106
106
|
const codecCache = new Map();
|
|
107
|
+
// Bridge between orderBy enum apply and filter apply.
|
|
108
|
+
// The orderBy enum runs on the PgSelectStep while the filter runs on
|
|
109
|
+
// a separate query-builder object. They share the same SQL `alias`
|
|
110
|
+
// reference, so we use a WeakMap keyed by that alias to pass the
|
|
111
|
+
// requested sort direction from the orderBy (which fires first) to
|
|
112
|
+
// the filter (which fires second and has the score expression).
|
|
113
|
+
const _pendingOrderDirections = new WeakMap();
|
|
107
114
|
/**
|
|
108
115
|
* Get (or compute) the adapter columns for a given codec.
|
|
109
116
|
*
|
|
@@ -453,10 +460,18 @@ export function createUnifiedSearchPlugin(options) {
|
|
|
453
460
|
codec: codec,
|
|
454
461
|
attributeName: column.attributeName,
|
|
455
462
|
});
|
|
456
|
-
const
|
|
463
|
+
const orderKey = `unified_order_${adapter.name}_${baseFieldName}`;
|
|
457
464
|
const makePlan = (direction) => (step) => {
|
|
458
|
-
|
|
459
|
-
|
|
465
|
+
// Store the requested direction keyed by the SQL alias so
|
|
466
|
+
// the filter's apply (which runs second) can read it.
|
|
467
|
+
const aliasKey = step?.alias;
|
|
468
|
+
if (aliasKey) {
|
|
469
|
+
let dirs = _pendingOrderDirections.get(aliasKey);
|
|
470
|
+
if (!dirs) {
|
|
471
|
+
dirs = {};
|
|
472
|
+
_pendingOrderDirections.set(aliasKey, dirs);
|
|
473
|
+
}
|
|
474
|
+
dirs[orderKey] = direction;
|
|
460
475
|
}
|
|
461
476
|
};
|
|
462
477
|
const ascName = inflection.pgSearchOrderByEnum(codec, column.attributeName, adapter.name, adapter.scoreSemantics.metric, true);
|
|
@@ -484,8 +499,14 @@ export function createUnifiedSearchPlugin(options) {
|
|
|
484
499
|
const searchScoreAscName = inflection.constantCase('search_score_asc');
|
|
485
500
|
const searchScoreDescName = inflection.constantCase('search_score_desc');
|
|
486
501
|
const makeSearchScorePlan = (direction) => (step) => {
|
|
487
|
-
|
|
488
|
-
|
|
502
|
+
const aliasKey = step?.alias;
|
|
503
|
+
if (aliasKey) {
|
|
504
|
+
let dirs = _pendingOrderDirections.get(aliasKey);
|
|
505
|
+
if (!dirs) {
|
|
506
|
+
dirs = {};
|
|
507
|
+
_pendingOrderDirections.set(aliasKey, dirs);
|
|
508
|
+
}
|
|
509
|
+
dirs['unified_order_search_score'] = direction;
|
|
489
510
|
}
|
|
490
511
|
};
|
|
491
512
|
newValues = build.extend(newValues, {
|
|
@@ -581,11 +602,11 @@ export function createUnifiedSearchPlugin(options) {
|
|
|
581
602
|
qb.setMeta(scoreMetaKey, {
|
|
582
603
|
selectIndex: scoreIndex,
|
|
583
604
|
});
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
const
|
|
588
|
-
const explicitDir =
|
|
605
|
+
// ORDER BY: read the direction stored by the orderBy
|
|
606
|
+
// enum (which ran first) via the shared alias key.
|
|
607
|
+
const orderKey = `unified_order_${adapter.name}_${baseFieldName}`;
|
|
608
|
+
const dirs = _pendingOrderDirections.get($condition.alias);
|
|
609
|
+
const explicitDir = dirs?.[orderKey];
|
|
589
610
|
if (explicitDir) {
|
|
590
611
|
qb.orderBy({
|
|
591
612
|
fragment: result.scoreExpression,
|
|
@@ -647,17 +668,17 @@ export function createUnifiedSearchPlugin(options) {
|
|
|
647
668
|
qb.setMeta(scoreMetaKey, {
|
|
648
669
|
selectIndex: scoreIndex,
|
|
649
670
|
});
|
|
650
|
-
// ORDER BY:
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
}
|
|
671
|
+
// ORDER BY: read the direction stored by the orderBy
|
|
672
|
+
// enum (which ran first) via the shared alias key.
|
|
673
|
+
const orderKey = `unified_order_${adapter.name}_${baseFieldName}`;
|
|
674
|
+
const dirs = _pendingOrderDirections.get($condition.alias);
|
|
675
|
+
const explicitDir = dirs?.[orderKey];
|
|
676
|
+
if (explicitDir) {
|
|
677
|
+
qb.orderBy({
|
|
678
|
+
fragment: result.scoreExpression,
|
|
679
|
+
codec: TYPES.float,
|
|
680
|
+
direction: explicitDir,
|
|
681
|
+
});
|
|
661
682
|
}
|
|
662
683
|
}
|
|
663
684
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "graphile-search",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.7",
|
|
4
4
|
"description": "Unified PostGraphile v5 search plugin — abstracts tsvector, BM25, pg_trgm, and pgvector behind a single adapter-based architecture with composite searchScore",
|
|
5
5
|
"author": "Constructive <developers@constructive.io>",
|
|
6
6
|
"homepage": "https://github.com/constructive-io/constructive",
|
|
@@ -62,5 +62,5 @@
|
|
|
62
62
|
"hybrid-search",
|
|
63
63
|
"searchScore"
|
|
64
64
|
],
|
|
65
|
-
"gitHead": "
|
|
65
|
+
"gitHead": "fc23b83307d007a14e54b1d0fc36614b9650a5dc"
|
|
66
66
|
}
|
package/plugin.js
CHANGED
|
@@ -107,6 +107,13 @@ function createUnifiedSearchPlugin(options) {
|
|
|
107
107
|
const { adapters, enableSearchScore = true, enableFullTextSearch = true } = options;
|
|
108
108
|
// Per-codec cache of discovered columns, keyed by codec name
|
|
109
109
|
const codecCache = new Map();
|
|
110
|
+
// Bridge between orderBy enum apply and filter apply.
|
|
111
|
+
// The orderBy enum runs on the PgSelectStep while the filter runs on
|
|
112
|
+
// a separate query-builder object. They share the same SQL `alias`
|
|
113
|
+
// reference, so we use a WeakMap keyed by that alias to pass the
|
|
114
|
+
// requested sort direction from the orderBy (which fires first) to
|
|
115
|
+
// the filter (which fires second and has the score expression).
|
|
116
|
+
const _pendingOrderDirections = new WeakMap();
|
|
110
117
|
/**
|
|
111
118
|
* Get (or compute) the adapter columns for a given codec.
|
|
112
119
|
*
|
|
@@ -456,10 +463,18 @@ function createUnifiedSearchPlugin(options) {
|
|
|
456
463
|
codec: codec,
|
|
457
464
|
attributeName: column.attributeName,
|
|
458
465
|
});
|
|
459
|
-
const
|
|
466
|
+
const orderKey = `unified_order_${adapter.name}_${baseFieldName}`;
|
|
460
467
|
const makePlan = (direction) => (step) => {
|
|
461
|
-
|
|
462
|
-
|
|
468
|
+
// Store the requested direction keyed by the SQL alias so
|
|
469
|
+
// the filter's apply (which runs second) can read it.
|
|
470
|
+
const aliasKey = step?.alias;
|
|
471
|
+
if (aliasKey) {
|
|
472
|
+
let dirs = _pendingOrderDirections.get(aliasKey);
|
|
473
|
+
if (!dirs) {
|
|
474
|
+
dirs = {};
|
|
475
|
+
_pendingOrderDirections.set(aliasKey, dirs);
|
|
476
|
+
}
|
|
477
|
+
dirs[orderKey] = direction;
|
|
463
478
|
}
|
|
464
479
|
};
|
|
465
480
|
const ascName = inflection.pgSearchOrderByEnum(codec, column.attributeName, adapter.name, adapter.scoreSemantics.metric, true);
|
|
@@ -487,8 +502,14 @@ function createUnifiedSearchPlugin(options) {
|
|
|
487
502
|
const searchScoreAscName = inflection.constantCase('search_score_asc');
|
|
488
503
|
const searchScoreDescName = inflection.constantCase('search_score_desc');
|
|
489
504
|
const makeSearchScorePlan = (direction) => (step) => {
|
|
490
|
-
|
|
491
|
-
|
|
505
|
+
const aliasKey = step?.alias;
|
|
506
|
+
if (aliasKey) {
|
|
507
|
+
let dirs = _pendingOrderDirections.get(aliasKey);
|
|
508
|
+
if (!dirs) {
|
|
509
|
+
dirs = {};
|
|
510
|
+
_pendingOrderDirections.set(aliasKey, dirs);
|
|
511
|
+
}
|
|
512
|
+
dirs['unified_order_search_score'] = direction;
|
|
492
513
|
}
|
|
493
514
|
};
|
|
494
515
|
newValues = build.extend(newValues, {
|
|
@@ -584,11 +605,11 @@ function createUnifiedSearchPlugin(options) {
|
|
|
584
605
|
qb.setMeta(scoreMetaKey, {
|
|
585
606
|
selectIndex: scoreIndex,
|
|
586
607
|
});
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
const
|
|
591
|
-
const explicitDir =
|
|
608
|
+
// ORDER BY: read the direction stored by the orderBy
|
|
609
|
+
// enum (which ran first) via the shared alias key.
|
|
610
|
+
const orderKey = `unified_order_${adapter.name}_${baseFieldName}`;
|
|
611
|
+
const dirs = _pendingOrderDirections.get($condition.alias);
|
|
612
|
+
const explicitDir = dirs?.[orderKey];
|
|
592
613
|
if (explicitDir) {
|
|
593
614
|
qb.orderBy({
|
|
594
615
|
fragment: result.scoreExpression,
|
|
@@ -650,17 +671,17 @@ function createUnifiedSearchPlugin(options) {
|
|
|
650
671
|
qb.setMeta(scoreMetaKey, {
|
|
651
672
|
selectIndex: scoreIndex,
|
|
652
673
|
});
|
|
653
|
-
// ORDER BY:
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
}
|
|
674
|
+
// ORDER BY: read the direction stored by the orderBy
|
|
675
|
+
// enum (which ran first) via the shared alias key.
|
|
676
|
+
const orderKey = `unified_order_${adapter.name}_${baseFieldName}`;
|
|
677
|
+
const dirs = _pendingOrderDirections.get($condition.alias);
|
|
678
|
+
const explicitDir = dirs?.[orderKey];
|
|
679
|
+
if (explicitDir) {
|
|
680
|
+
qb.orderBy({
|
|
681
|
+
fragment: result.scoreExpression,
|
|
682
|
+
codec: pg_1.TYPES.float,
|
|
683
|
+
direction: explicitDir,
|
|
684
|
+
});
|
|
664
685
|
}
|
|
665
686
|
}
|
|
666
687
|
}
|