Skip to content

docs(examples): add metadata filter operator snippets - #438

Open
moroshani wants to merge 4 commits into
usemoss:mainfrom
moroshani:docs/metadata-filter-operator-examples
Open

docs(examples): add metadata filter operator snippets#438
moroshani wants to merge 4 commits into
usemoss:mainfrom
moroshani:docs/metadata-filter-operator-examples

Conversation

@moroshani

@moroshani moroshani commented Jul 18, 2026

Copy link
Copy Markdown

Summary

  • Add four runnable TypeScript metadata filter examples for $eq, $and, $in, and $near under examples/javascript/metadata-filters/.
  • Share setup/query/cleanup logic so each operator snippet stays short and copyable.
  • Add npm scripts and README commands for the new examples.

Closes #417

Verification

  • npm ci
  • npm run type-check
  • npm run lint
  • git diff --check

Notes

The examples require real MOSS_PROJECT_ID and MOSS_PROJECT_KEY credentials to run end-to-end. I verified them with the local TypeScript and ESLint checks; at runtime they create a temporary index, run one filtered query, and delete the index.

Review in cubic

Summary by CodeRabbit

  • New Features

    • Added JavaScript examples demonstrating metadata filtering with equality, conjunction, inclusion, and proximity operators.
    • Added sample queries for matching categories, cities, and locations near Times Square.
    • Added reusable example setup, execution, result output, cleanup, and error handling.
  • Documentation

    • Added instructions for running each metadata filter example.
  • Chores

    • Added npm scripts to launch the filter demonstrations.

@CLAassistant

CLAassistant commented Jul 18, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 7 files

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

Comment thread examples/javascript/metadata-filters/shared.ts Outdated
Comment thread examples/javascript/metadata-filters/shared.ts Outdated
Comment thread examples/javascript/metadata-filters/shared.ts Outdated
@moroshani

moroshani commented Jul 18, 2026

Copy link
Copy Markdown
Author

Update: I was able to complete the CLA from another device. The CLA check now shows signed. Thanks.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds runnable, copy-pasteable TypeScript examples demonstrating metadata filter operators in the JavaScript examples package (examples/javascript/), aligning with the repo’s goal of providing practical SDK usage snippets.

Changes:

  • Added four runnable operator-focused scripts for $eq, $and, $in, and $near under examples/javascript/metadata-filters/.
  • Introduced a shared helper to centralize setup (env, temporary index creation/loading), querying, and teardown.
  • Updated the JavaScript examples README and package.json scripts to make running the new samples straightforward.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
examples/javascript/README.md Documents the new metadata filter operator samples and how to run them.
examples/javascript/package.json Adds npm run metadata:* scripts to run each operator snippet.
examples/javascript/metadata-filters/shared.ts Shared runner that creates a temporary index, performs a filtered query, prints results, and cleans up.
examples/javascript/metadata-filters/eq.ts Runnable $eq filter example.
examples/javascript/metadata-filters/and.ts Runnable $and composition example.
examples/javascript/metadata-filters/in.ts Runnable $in filter example.
examples/javascript/metadata-filters/near.ts Runnable $near geo-distance filter example.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread examples/javascript/metadata-filters/shared.ts
@github-actions

github-actions Bot commented Jul 25, 2026

Copy link
Copy Markdown

Codex review

No issues found.

Comment thread examples/javascript/metadata-filters/shared.ts Outdated
Comment thread examples/javascript/metadata-filters/shared.ts
@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Added a shared temporary-index runner and four runnable JavaScript examples for $eq, $and, $in, and $near metadata filters. Added npm scripts and README documentation for executing the examples.

Changes

Metadata filter examples

Layer / File(s) Summary
Shared metadata filter runner
examples/javascript/metadata-filters/shared.ts
Adds sample documents, environment validation, temporary Moss index creation and cleanup, filtered hybrid queries, and result output.
Operator samples and commands
examples/javascript/metadata-filters/*.ts, examples/javascript/package.json, examples/javascript/README.md
Adds runnable $eq, $and, $in, and $near examples with failure handling, npm scripts, and usage documentation.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant OperatorExample
  participant runMetadataFilterExample
  participant Moss
  participant TemporaryIndex
  OperatorExample->>runMetadataFilterExample: provide metadata filter
  runMetadataFilterExample->>Moss: create temporary index
  Moss->>TemporaryIndex: load sample documents
  runMetadataFilterExample->>TemporaryIndex: execute filtered hybrid query
  TemporaryIndex-->>runMetadataFilterExample: return results
  runMetadataFilterExample->>Moss: delete temporary index
Loading

Suggested reviewers: ashvathsureshkumar

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the addition of metadata filter operator examples and matches the main change.
Linked Issues check ✅ Passed The PR adds runnable examples for all requested operators: $eq, $and, $in, and $near, under the examples folder [#417].
Out of Scope Changes check ✅ Passed The README, npm scripts, and shared setup directly support the requested runnable metadata filter examples.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@examples/javascript/metadata-filters/shared.ts`:
- Around line 71-81: Update the temporary index name construction in the
metadata filter example to use randomUUID() as its unique suffix instead of
Date.now(). Keep the existing operator-based prefix and cleanup flow unchanged.
- Around line 102-109: Update the cleanup flow in the surrounding try/finally
logic so deleteIndex’s Promise<boolean> result must be true; when no primary
error exists, propagate cleanup failures by rejecting on a thrown error or a
non-true result. Preserve the primary operation error when both the primary
operation and cleanup fail, and keep the existing cleanupNeeded guard and
warning behavior as appropriate.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: a23bedd1-9a78-45aa-a8e1-d1fc3fc0cde4

📥 Commits

Reviewing files that changed from the base of the PR and between de26a4b and edd5105.

📒 Files selected for processing (7)
  • examples/javascript/README.md
  • examples/javascript/metadata-filters/and.ts
  • examples/javascript/metadata-filters/eq.ts
  • examples/javascript/metadata-filters/in.ts
  • examples/javascript/metadata-filters/near.ts
  • examples/javascript/metadata-filters/shared.ts
  • examples/javascript/package.json

Comment on lines +71 to +81
const indexName = `metadata-filter-${example.operator.slice(1)}-${Date.now()}`;
const client = new MossClient(projectId, projectKey);
let cleanupNeeded = false;

try {
console.log(`Moss metadata filter example: ${example.operator}`);
console.log(example.description);

console.log(`\nCreating temporary index: ${indexName}`);
cleanupNeeded = true;
await client.createIndex(indexName, documents, { modelId: "moss-minilm" });

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -eu

printf '%s\n' '--- candidate files ---'
git ls-files | rg '(^|/)(package(-lock)?\.json|pnpm-lock\.yaml|yarn\.lock|shared\.ts)$|examples/javascript/metadata-filters'

printf '%s\n' '--- target file ---'
cat -n examples/javascript/metadata-filters/shared.ts | sed -n '1,140p'

printf '%s\n' '--- package references ---'
rg -n --hidden -g '!node_modules' -g '!dist' -g '!build' '`@moss-dev/moss`|moss-dev|MossClient|deleteIndex|createIndex' . | head -250

printf '%s\n' '--- lockfile versions ---'
rg -n --hidden -g 'package.json' -g 'package-lock.json' -g 'pnpm-lock.yaml' -g 'yarn.lock' '`@moss-dev/moss`|1\.3\.0' .

Repository: usemoss/moss

Length of output: 50368


🏁 Script executed:

#!/bin/bash
set -eu

printf '%s\n' '--- target directory files ---'
find examples/javascript/metadata-filters -maxdepth 2 -type f -print

printf '%s\n' '--- index lifecycle call sites ---'
rg -n -C 8 'cleanupNeeded|createIndex\(|deleteIndex\(' examples/javascript/metadata-filters

printf '%s\n' '--- dependency manifests and lockfiles ---'
find . -maxdepth 4 -type f \( -name 'package.json' -o -name 'package-lock.json' -o -name 'pnpm-lock.yaml' -o -name 'yarn.lock' \) -print

Repository: usemoss/moss

Length of output: 6215


🏁 Script executed:

#!/bin/bash
set -eu

printf '%s\n' '--- examples/javascript dependency declarations ---'
cat examples/javascript/package.json
rg -n -C 4 '"`@moss-dev/moss`"|moss-[0-9]' examples/javascript/package-lock.json

printf '%s\n' '--- SDK package and lifecycle implementation ---'
cat sdks/javascript/sdk/package.json | sed -n '1,180p'
rg -n -C 8 'createIndex|deleteIndex|index already|already exists|Index.*exist|delete.*data' sdks/javascript/sdk/src sdks/javascript/sdk/package.json

printf '%s\n' '--- SDK lockfile package versions ---'
rg -n -C 6 '"`@moss-dev/moss`"|moss-core' sdks/javascript/sdk/package-lock.json | head -160

Repository: usemoss/moss

Length of output: 22423


🌐 Web query:

@moss-dev/moss 1.3.0 createIndex deleteIndex existing index name documentation

💡 Result:

In the @moss-dev/moss SDK (v1.3.0 and later), the MossClient provides asynchronous methods for index lifecycle management. createIndex(indexName, docs, options?) The createIndex method initializes, uploads, and builds a new index. It accepts the index name, an array of documents (DocumentInfo[]), and optional configuration such as modelId (defaults to 'moss-minilm') and an onProgress callback [1][2]. Example: await client.createIndex('my-index', [ { id: 'doc-1', text: '...' } ], { modelId: 'moss-minilm' }); Important behavior: The method will throw an error if an index with the specified indexName already exists [2]. deleteIndex(indexName) The deleteIndex method removes an index and all associated data from the project [1][2]. Example: await client.deleteIndex('my-index'); Handling Existing Index Names Because createIndex throws an error if an index name is already in use, you should verify existence or choose a unique name before creation. To update data within an existing index rather than recreating it, use the addDocs method with the upsert option set to true [1]. Example: await client.addDocs('my-index', [ { id: 'doc-2', text: 'updated text' } ], { upsert: true });

Citations:


🏁 Script executed:

#!/bin/bash
set -eu

tmp="$(mktemp)"
trap 'rm -f "$tmp"' EXIT
curl -fsSL 'https://registry.npmjs.org/@moss-dev/moss/-/moss-1.3.0.tgz' -o "$tmp"

printf '%s\n' '--- package metadata ---'
tar -xOf "$tmp" package/package.json | jq '{name,version,type,exports}'

printf '%s\n' '--- bundled lifecycle behavior ---'
tar -tzf "$tmp" | rg 'dist/.*\.(js|d\.ts)$' | head -30
for path in $(tar -tzf "$tmp" | rg 'dist/.*\.(js|d\.ts)$' | head -20); do
  tar -xOf "$tmp" "$path" 2>/dev/null | rg -n -C 3 'already exists|deleteIndex|all its data|createIndex' && printf 'FILE: %s\n' "$path"
done

Repository: usemoss/moss

Length of output: 26262


Use an ownership-safe temporary index name.

If two runs use the same example.operator within one millisecond, Date.now() produces the same index name. createIndex rejects existing names, but cleanupNeeded is already true, so the failed run can delete the other run's index and data.

Use randomUUID() for the suffix.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/javascript/metadata-filters/shared.ts` around lines 71 - 81, Update
the temporary index name construction in the metadata filter example to use
randomUUID() as its unique suffix instead of Date.now(). Keep the existing
operator-based prefix and cleanup flow unchanged.

Comment on lines +102 to +109
} finally {
if (cleanupNeeded) {
console.log(`\nDeleting temporary index: ${indexName}`);
try {
await client.deleteIndex(indexName);
} catch (cleanupError) {
console.warn(`Failed to delete temporary index: ${indexName}`, cleanupError);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -eu

printf '%s\n' '--- target file ---'
cat -n examples/javascript/metadata-filters/shared.ts | sed -n '1,150p'

printf '%s\n' '--- repository references ---'
rg -n --glob '!node_modules' --glob '!dist' --glob '!build' \
  'runMetadataFilterExample|deleteIndex\(|cleanupNeeded|MossClient' .

printf '%s\n' '--- package and workflow context ---'
git ls-files | rg '(^|/)(package\.json|package-lock\.json|npm-shrinkwrap\.json|yarn\.lock|pnpm-lock\.yaml|README|.*metadata.*filter.*|.*workflow.*)$' | head -200

Repository: usemoss/moss

Length of output: 50369


🌐 Web query:

Moss JavaScript SDK MossClient deleteIndex boolean return result documentation

💡 Result:

Moss JavaScript SDK: MossClient.deleteIndex(indexName) returns a Promise. The official JS API reference for MossClient shows: - deleteIndex(indexName): Promise - “Promise that resolves to true if successful” [1]. - It deletes the index and all its data [1]. Example (from docs): const deleted = await client.deleteIndex('old-index'); // deleted is a boolean (true if successful) [1] Notes: - The method throws if the index does not exist [1]. - The docs also describe index deletion at the API level (deleteIndex) as deleting the index record/assets (not changing the JS return type) [2].

Citations:


🏁 Script executed:

#!/bin/bash
set -eu

printf '%s\n' '--- JavaScript SDK files ---'
git ls-files | rg '(^|/)(package\.json|package-lock\.json|pnpm-lock\.yaml|yarn\.lock|MossClient|client\.(ts|js)|index\.(ts|js))$' | rg '(^sdks/javascript/|^examples/javascript/|^packages/vitepress-plugin-moss/demo-site/documentation/docs/reference/js/classes/MossClient\.md$|(^|/)package(-lock)?\.json$|pnpm-lock|yarn\.lock)' | head -200

printf '%s\n' '--- local API documentation ---'
cat -n packages/vitepress-plugin-moss/demo-site/documentation/docs/reference/js/classes/MossClient.md | sed -n '150,200p'

printf '%s\n' '--- SDK deleteIndex declarations and implementations ---'
rg -n -A25 -B8 'deleteIndex' sdks/javascript packages/vitepress-plugin-moss/demo-site/documentation/docs/reference/js 2>/dev/null | head -240

printf '%s\n' '--- target example package scripts and dependency pins ---'
find examples/javascript -maxdepth 3 -type f \( -name 'package.json' -o -name 'package-lock.json' -o -name 'pnpm-lock.yaml' -o -name 'yarn.lock' \) -print
rg -n -A8 -B8 '"(`@moss-dev/moss`|metadata-filters)|metadata-filters|runMetadataFilterExample' examples/javascript package.json pnpm-lock.yaml yarn.lock package-lock.json 2>/dev/null | head -240

Repository: usemoss/moss

Length of output: 43987


🌐 Web query:

site:docs.moss.dev/docs/reference/js/classes/MossClient deleteIndex Promise<boolean> false return semantics

💡 Result:

In the context of the Moss SDK, the deleteIndex method returns a Promise that resolves to a boolean value [1]. A return value of true indicates that the index was successfully deleted [1]. If the operation fails because the specified index does not exist, the method is documented to throw an error rather than returning false [1]. Semantics for boolean return values in similar asynchronous deletion APIs typically signify the outcome of the requested operation, where true confirms success and false may indicate that the target did not exist or could not be removed, depending on the specific library implementation [1].

Citations:


🏁 Script executed:

#!/bin/bash
set -eu

printf '%s\n' '--- example lockfile resolution ---'
python3 - <<'PY'
import json
p = json.load(open("examples/javascript/package-lock.json"))
for key, value in p.get("packages", {}).items():
    if "`@moss-dev/moss`" in key or key == "node_modules/@moss-dev/moss":
        print(key, value.get("version"), value.get("resolved"))
print("root dependency:", p["packages"][""].get("dependencies", {}).get("`@moss-dev/moss`"))
PY

printf '%s\n' '--- SDK package metadata ---'
cat -n sdks/javascript/sdk/package.json | sed -n '1,130p'
cat -n sdks/javascript/sdk/src/client/mossClient.ts | sed -n '130,160p'

printf '%s\n' '--- binding implementation references ---'
rg -n -A12 -B8 'deleteIndex' sdks/javascript/bindings sdks/javascript/sdk/src | head -180

printf '%s\n' '--- metadata-filter entrypoint error handling ---'
for f in examples/javascript/metadata-filters/*.ts; do
  printf '\n--- %s ---\n' "$f"
  cat -n "$f"
done

Repository: usemoss/moss

Length of output: 19387


🌐 Web query:

site:github.com/usemoss/moss "@moss-dev/moss" "deleteIndex" "Promise<boolean>"

💡 Result:

The @moss-dev/moss TypeScript SDK does not provide a method named deleteIndex [1][2]. Based on the official repository documentation and codebase, index management in the Moss ecosystem is typically handled via the Moss CLI [3][4] or through cloud-side administration rather than direct SDK methods intended for index deletion [1][2]. The SDK focuses on operations such as createIndex, loadIndex, and document CRUD (e.g., adding or deleting documents) [1][2][5][6]. For index management tasks like deleting an index, users are generally expected to use the moss CLI tool [3][4] or the Moss Cloud interface [1][2]. If you are attempting to remove an index programmatically, you should verify the current capabilities via the Moss CLI's help commands or the official docs.moss.dev documentation [7][4].

Citations:


🏁 Script executed:

#!/bin/bash
set -eu

node - <<'JS'
async function current({ operationError, cleanupResult, cleanupError }) {
  let cleanupNeeded = false;
  try {
    cleanupNeeded = true;
    if (operationError) throw new Error("operation");
  } finally {
    if (cleanupNeeded) {
      try {
        if (cleanupError) throw new Error("cleanup");
        return cleanupResult; // current code ignores this result
      } catch {
        // current code logs and resolves when the main operation succeeded
      }
    }
  }
}

async function proposed({ operationError, cleanupResult, cleanupError }) {
  let cleanupNeeded = false;
  let operationSucceeded = false;
  try {
    cleanupNeeded = true;
    if (operationError) throw new Error("operation");
    operationSucceeded = true;
  } finally {
    if (cleanupNeeded) {
      try {
        if (cleanupError) throw new Error("cleanup");
        if (cleanupResult !== true) throw new Error("cleanup returned false");
      } catch (error) {
        if (operationSucceeded) throw error;
      }
    }
  }
}

for (const scenario of [
  ["primary failure + cleanup failure", { operationError: true, cleanupError: true }],
  ["success + cleanup throw", { cleanupError: true }],
  ["success + false result", { cleanupResult: false }],
  ["success + true result", { cleanupResult: true }],
]) {
  const [name, input] = scenario;
  const outcomes = [];
  for (const fn of [current, proposed]) {
    try {
      await fn(input);
      outcomes.push("resolve");
    } catch (error) {
      outcomes.push(`reject:${error.message}`);
    }
  }
  console.log(name, "current=", outcomes[0], "proposed=", outcomes[1]);
}
JS

Repository: usemoss/moss

Length of output: 440


Fail when temporary-index cleanup fails without a primary error.

When the primary operation succeeds, reject if deleteIndex throws or returns a value other than true. Preserve the primary error when both operations fail. The pinned @moss-dev/moss 1.3.0 SDK returns Promise<boolean> for deleteIndex.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/javascript/metadata-filters/shared.ts` around lines 102 - 109,
Update the cleanup flow in the surrounding try/finally logic so deleteIndex’s
Promise<boolean> result must be true; when no primary error exists, propagate
cleanup failures by rejecting on a thrown error or a non-true result. Preserve
the primary operation error when both the primary operation and cleanup fail,
and keep the existing cleanupNeeded guard and warning behavior as appropriate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Good first issue: runnable example per metadata operator

4 participants