mbd-studio-sdk 2.0.3
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/V1/Studio.js +262 -0
- package/V1/features/Features.js +249 -0
- package/V1/index.js +1 -0
- package/V1/ranking/Ranking.js +477 -0
- package/V1/scoring/Scoring.js +187 -0
- package/V1/search/Search.js +673 -0
- package/V1/search/filters/ConsoleAccountFilter.js +18 -0
- package/V1/search/filters/CustomFilter.js +16 -0
- package/V1/search/filters/DateFilter.js +23 -0
- package/V1/search/filters/Filter.js +20 -0
- package/V1/search/filters/GeoFilter.js +16 -0
- package/V1/search/filters/GroupBoostFilter.js +26 -0
- package/V1/search/filters/IsNullFilter.js +14 -0
- package/V1/search/filters/MatchFilter.js +16 -0
- package/V1/search/filters/NotNullFilter.js +14 -0
- package/V1/search/filters/NumericFilter.js +18 -0
- package/V1/search/filters/TermFilter.js +16 -0
- package/V1/search/filters/TermsFilter.js +16 -0
- package/V1/search/filters/TermsLookupFilter.js +20 -0
- package/V1/search/filters/index.js +13 -0
- package/V1/utils/indexUtils.js +12 -0
- package/index.js +4 -0
- package/package.json +14 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Filter } from './Filter.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Date range filter. Accepts dateFrom/dateTo (ISO 8601) and exposes value as { date_from, date_to } for the API.
|
|
5
|
+
*/
|
|
6
|
+
export class DateFilter extends Filter {
|
|
7
|
+
/**
|
|
8
|
+
* @param {string} field - Date field to filter (e.g. "item_creation_timestamp")
|
|
9
|
+
* @param {string | null} [dateFrom=null] - Start date (ISO 8601)
|
|
10
|
+
* @param {string | null} [dateTo=null] - End date (ISO 8601)
|
|
11
|
+
* @param {number | null} [boost=null] - Optional boost multiplier (0.1–100)
|
|
12
|
+
*/
|
|
13
|
+
constructor(field, dateFrom = null, dateTo = null, boost = null) {
|
|
14
|
+
super('date', field, boost);
|
|
15
|
+
if (dateFrom == null && dateTo == null) {
|
|
16
|
+
throw new Error('DateFilter: at least one of dateFrom or dateTo must be provided');
|
|
17
|
+
}
|
|
18
|
+
const value = {};
|
|
19
|
+
if (dateFrom != null) value.date_from = dateFrom;
|
|
20
|
+
if (dateTo != null) value.date_to = dateTo;
|
|
21
|
+
this.value = value;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Abstract base class for filter objects used in Search include, exclude and boost arrays.
|
|
3
|
+
* All subclasses have filter (type), field, and optional boost.
|
|
4
|
+
* Use null for optional values so logic can be transposed to Python.
|
|
5
|
+
*/
|
|
6
|
+
export class Filter {
|
|
7
|
+
/**
|
|
8
|
+
* @param {string} filterType - Filter type (e.g. "term", "terms", "numeric")
|
|
9
|
+
* @param {string} field - Field to filter on
|
|
10
|
+
* @param {number | null} [boost=null] - Optional boost multiplier
|
|
11
|
+
*/
|
|
12
|
+
constructor(filterType, field, boost = null) {
|
|
13
|
+
if (new.target === Filter) {
|
|
14
|
+
throw new Error('Filter is abstract and cannot be instantiated directly');
|
|
15
|
+
}
|
|
16
|
+
this.filter = filterType;
|
|
17
|
+
this.field = field;
|
|
18
|
+
this.boost = boost;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Filter } from './Filter.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Geographic distance filter. Value items format: "geo:lat,lon".
|
|
5
|
+
*/
|
|
6
|
+
export class GeoFilter extends Filter {
|
|
7
|
+
/**
|
|
8
|
+
* @param {string} field - Geo point field (e.g. "location")
|
|
9
|
+
* @param {string[]} value - Coordinates, e.g. ["geo:40.7128,-74.0060"]
|
|
10
|
+
* @param {number | null} [boost=null] - Optional boost multiplier (0.1–100)
|
|
11
|
+
*/
|
|
12
|
+
constructor(field, value, boost = null) {
|
|
13
|
+
super('geo', field, boost);
|
|
14
|
+
this.value = value;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Filter } from './Filter.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Hierarchical boosting from a grouped lookup index (boost lists only).
|
|
5
|
+
* Paths in the document: {group}_01, {group}_02, ... {group}_n.
|
|
6
|
+
*/
|
|
7
|
+
export class GroupBoostFilter extends Filter {
|
|
8
|
+
/**
|
|
9
|
+
* @param {string} lookup_index - Lookup index (e.g. "polymarket-wallets", "user-prefs")
|
|
10
|
+
* @param {string} field - Target field in the lookup index (e.g. "ai_labels_med")
|
|
11
|
+
* @param {string} value - Lookup document ID
|
|
12
|
+
* @param {string} group - Group path prefix (e.g. "label" -> label_01, label_02, ...)
|
|
13
|
+
* @param {number | null} [min_boost=null] - Minimum boost (default 1)
|
|
14
|
+
* @param {number | null} [max_boost=null] - Maximum boost (default 5)
|
|
15
|
+
* @param {number | null} [n=null] - Number of groups (default 10)
|
|
16
|
+
*/
|
|
17
|
+
constructor(lookup_index, field, value, group, min_boost = null, max_boost = null, n = null) {
|
|
18
|
+
super('group_boost', field, null);
|
|
19
|
+
this.lookup_index = lookup_index;
|
|
20
|
+
this.value = value;
|
|
21
|
+
this.group = group;
|
|
22
|
+
this.min_boost = min_boost;
|
|
23
|
+
this.max_boost = max_boost;
|
|
24
|
+
this.n = n;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Filter } from './Filter.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Match documents where the field is null/missing.
|
|
5
|
+
*/
|
|
6
|
+
export class IsNullFilter extends Filter {
|
|
7
|
+
/**
|
|
8
|
+
* @param {string} field - Field that must be empty/null (e.g. "embed_items")
|
|
9
|
+
* @param {number | null} [boost=null] - Optional boost multiplier (0.1–100)
|
|
10
|
+
*/
|
|
11
|
+
constructor(field, boost = null) {
|
|
12
|
+
super('is_null', field, boost);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Filter } from './Filter.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Full-text search on a text field (keywords array).
|
|
5
|
+
*/
|
|
6
|
+
export class MatchFilter extends Filter {
|
|
7
|
+
/**
|
|
8
|
+
* @param {string} field - Text field to match against (e.g. "text")
|
|
9
|
+
* @param {string[]} value - Keywords to match (e.g. ["technical", "development"])
|
|
10
|
+
* @param {number | null} [boost=null] - Optional boost multiplier (0.1–100)
|
|
11
|
+
*/
|
|
12
|
+
constructor(field, value, boost = null) {
|
|
13
|
+
super('match', field, boost);
|
|
14
|
+
this.value = value;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Filter } from './Filter.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Match documents where the field exists and has a value.
|
|
5
|
+
*/
|
|
6
|
+
export class NotNullFilter extends Filter {
|
|
7
|
+
/**
|
|
8
|
+
* @param {string} field - Field that must exist (e.g. "user_id")
|
|
9
|
+
* @param {number | null} [boost=null] - Optional boost multiplier (0.1–100)
|
|
10
|
+
*/
|
|
11
|
+
constructor(field, boost = null) {
|
|
12
|
+
super('not_null', field, boost);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Filter } from './Filter.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Range comparison on a numeric field (>, >=, <, <=).
|
|
5
|
+
*/
|
|
6
|
+
export class NumericFilter extends Filter {
|
|
7
|
+
/**
|
|
8
|
+
* @param {string} field - Field to filter on (e.g. "score_popular")
|
|
9
|
+
* @param {">" | ">=" | "<" | "<="} operator - Comparison operator
|
|
10
|
+
* @param {number} value - Numeric threshold value
|
|
11
|
+
* @param {number | null} [boost=null] - Optional boost multiplier (0.1–100)
|
|
12
|
+
*/
|
|
13
|
+
constructor(field, operator, value, boost = null) {
|
|
14
|
+
super('numeric', field, boost);
|
|
15
|
+
this.operator = operator;
|
|
16
|
+
this.value = value;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Filter } from './Filter.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Exact match on a keyword/text field (single value).
|
|
5
|
+
*/
|
|
6
|
+
export class TermFilter extends Filter {
|
|
7
|
+
/**
|
|
8
|
+
* @param {string} field - Field to filter on (e.g. "lang")
|
|
9
|
+
* @param {string} value - Exact value to match (e.g. "en")
|
|
10
|
+
* @param {number | null} [boost=null] - Optional boost multiplier (0.1–100)
|
|
11
|
+
*/
|
|
12
|
+
constructor(field, value, boost = null) {
|
|
13
|
+
super('term', field, boost);
|
|
14
|
+
this.value = value;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Filter } from './Filter.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Multiple values where at least one must match (OR logic).
|
|
5
|
+
*/
|
|
6
|
+
export class TermsFilter extends Filter {
|
|
7
|
+
/**
|
|
8
|
+
* @param {string} field - Field to filter on (e.g. "channels")
|
|
9
|
+
* @param {string[]} value - Values to match (e.g. ["en", "fr"])
|
|
10
|
+
* @param {number | null} [boost=null] - Optional boost multiplier (0.1–100)
|
|
11
|
+
*/
|
|
12
|
+
constructor(field, value, boost = null) {
|
|
13
|
+
super('terms', field, boost);
|
|
14
|
+
this.value = value;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Filter } from './Filter.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Match field values against terms from another Elasticsearch document.
|
|
5
|
+
*/
|
|
6
|
+
export class TermsLookupFilter extends Filter {
|
|
7
|
+
/**
|
|
8
|
+
* @param {string} lookup_index - Index to look up terms from (e.g. "user-prefs", "following-graph")
|
|
9
|
+
* @param {string} field - Target field in the current index to match (e.g. "item_id", "user_id")
|
|
10
|
+
* @param {string} value - Document ID in lookup_index
|
|
11
|
+
* @param {string} path - JSON path in the lookup document (e.g. "followed_items")
|
|
12
|
+
* @param {number | null} [boost=null] - Optional boost multiplier (0.1–100)
|
|
13
|
+
*/
|
|
14
|
+
constructor(lookup_index, field, value, path, boost = null) {
|
|
15
|
+
super('terms_lookup', field, boost);
|
|
16
|
+
this.lookup_index = lookup_index;
|
|
17
|
+
this.value = value;
|
|
18
|
+
this.path = path;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { Filter } from './Filter.js';
|
|
2
|
+
export { TermFilter } from './TermFilter.js';
|
|
3
|
+
export { TermsFilter } from './TermsFilter.js';
|
|
4
|
+
export { NumericFilter } from './NumericFilter.js';
|
|
5
|
+
export { MatchFilter } from './MatchFilter.js';
|
|
6
|
+
export { GeoFilter } from './GeoFilter.js';
|
|
7
|
+
export { DateFilter } from './DateFilter.js';
|
|
8
|
+
export { IsNullFilter } from './IsNullFilter.js';
|
|
9
|
+
export { NotNullFilter } from './NotNullFilter.js';
|
|
10
|
+
export { CustomFilter } from './CustomFilter.js';
|
|
11
|
+
export { GroupBoostFilter } from './GroupBoostFilter.js';
|
|
12
|
+
export { TermsLookupFilter } from './TermsLookupFilter.js';
|
|
13
|
+
export { ConsoleAccountFilter } from './ConsoleAccountFilter.js';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve index name from a hit _index (e.g. "farcaster-items-xyz" -> "farcaster-items").
|
|
3
|
+
* @param {string} index - Raw index string from a hit
|
|
4
|
+
* @returns {string | null}
|
|
5
|
+
*/
|
|
6
|
+
export function findIndex(index) {
|
|
7
|
+
const indexOptions = ['farcaster-items', 'zora-coins', 'polymarket-items', 'polymarket-wallets'];
|
|
8
|
+
for (const option of indexOptions) {
|
|
9
|
+
if (index.startsWith(option)) return option;
|
|
10
|
+
}
|
|
11
|
+
return null;
|
|
12
|
+
}
|
package/index.js
ADDED
package/package.json
ADDED