Skip to content

Latest commit

 

History

History
136 lines (107 loc) · 4.4 KB

File metadata and controls

136 lines (107 loc) · 4.4 KB
name search-nodejs
summary Couchbase Full-Text Search, vector search, hybrid search, and geospatial search for Node.js
description Couchbase Full-Text Search, vector search, hybrid search, and geospatial search for Node.js
compatibility Node.js SDK 4.x. Requires couchbase>=4.0.
metadata
last_verified min_server_version handoff
2026-05
7.0
condition skill
user asks about search concepts, index setup, or RAG patterns
search-concepts
condition skill
user asks about SQL++ queries
server-querying-nodejs
condition skill
user asks about CAS, bulk ops, sub-document, or SDK patterns
sdk-patterns-nodejs
condition skill
user asks about connection setup or SDK configuration
server-connection-nodejs

Couchbase Search — Node.js

Prerequisites — Index must exist before querying

Create an FTS index before running text or vector queries. Use the templates as a starting point:

See shared/server/search-concepts.md for setup instructions.

Full-Text Search

const { SearchQuery, SearchOptions } = require('couchbase');

const result = await cluster.searchQuery(
    'hotel-fts',
    SearchQuery.match('ocean view').field('description'),
    new SearchOptions({ limit: 10, fields: ['name', 'city', 'stars'] })
);
for (const row of result.rows)
    console.log(row.id, row.score, row.fields);

Vector Search

const { VectorSearch, VectorQuery } = require('couchbase');

const queryVector = await embeddingModel.encode(question); // number[]

const result = await cluster.searchQuery(
    'product-vector',
    VectorSearch.fromVectorQuery(
        VectorQuery.create('embedding', queryVector).numCandidates(5)
    ),
    new SearchOptions({ fields: ['name', 'description'] })
);

Hybrid Search

const { VectorSearch, VectorQuery, VectorQueryCombination } = require('couchbase');

const queryVector = await embeddingModel.encode(question); // number[]

const result = await cluster.searchQuery(
    'product-vector',
    VectorSearch.fromVectorQuery(
        VectorQuery.create('embedding', queryVector).numCandidates(10)
    ).withSearchQuery(SearchQuery.match('comfortable hotel').field('description'))
     .vectorQueryCombination(VectorQueryCombination.Or),
    new SearchOptions({ fields: ['name', 'description'], limit: 5 })
);

Geospatial Search

const result = await cluster.searchQuery(
    'hotel-geo',
    SearchQuery.geoDistance(37.7749, -122.4194, '10km').field('geo'),
    new SearchOptions({ limit: 20, fields: ['name', 'geo'] })
);

RYOW Consistency

const upsertResult = await collection.upsert('hotel::new', { name: 'New Hotel' });

const ms = couchbase.MutationState.from(upsertResult);

const result = await cluster.searchQuery(
    'hotel-fts',
    SearchQuery.match('New Hotel').field('name'),
    new SearchOptions({ consistentWith: ms, limit: 5 })
);

Pagination

// Page 3 (0-indexed skip)
const result = await cluster.searchQuery(
    'hotel-fts',
    SearchQuery.match('ocean view').field('description'),
    new SearchOptions({ limit: 10, skip: 20 })
);

Common Query Types

SearchQuery.match('ocean view').field('description')          // full-text with analysis
SearchQuery.term('airline').field('type')                     // exact token
SearchQuery.prefix('air').field('name')                       // prefix / autocomplete
SearchQuery.fuzzy('hotl').fuzziness(1)                        // typo-tolerant
SearchQuery.numericRange().min(3.0).max(5.0).field('stars')   // range
SearchQuery.conjuncts(                                        // AND
    SearchQuery.match('hotel').field('type'),
    SearchQuery.numericRange().min(4.0).field('stars')
)

SQL++ with FTS (Flex Index)

SELECT name, SEARCH_SCORE() AS score
FROM `travel-sample`.inventory.hotel AS h
WHERE SEARCH(h, {"query": {"match": "ocean view", "field": "description"}}, {"index": "hotel-fts"})
ORDER BY SEARCH_SCORE() DESC LIMIT 10;

Shared concepts: shared/server/search-concepts.md — prerequisites, hybrid search, RYOW, pagination, query types.