ArangoSearch views and full-text search capabilities for advanced querying, indexing, and real-time search functionality across collections.
Create and manage ArangoSearch views and SearchAlias views for advanced search capabilities.
/**
* Gets a reference to a view
* @param viewName - Name of the view
* @returns View instance
*/
view(viewName: string): View;
/**
* Creates a new view (ArangoSearch or SearchAlias)
* @param viewName - Name for the new view
* @param options - View creation options
* @returns Promise resolving to View instance
*/
createView(viewName: string, options: CreateViewOptions): Promise<View>;
/**
* Lists all views in the database
* @returns Promise resolving to array of View instances
*/
views(): Promise<View[]>;Usage Examples:
import { Database } from "arangojs";
const db = new Database();
// Create ArangoSearch view for full-text search
const searchView = await db.createView("article_search", {
type: "arangosearch",
links: {
articles: {
analyzers: ["text_en", "identity"],
fields: {
title: { analyzers: ["text_en"] },
content: { analyzers: ["text_en"] },
tags: { analyzers: ["identity"] },
author: {
fields: {
name: { analyzers: ["text_en"] }
}
}
},
includeAllFields: false,
storeValues: "none",
trackListPositions: false
},
comments: {
analyzers: ["text_en"],
fields: {
text: { analyzers: ["text_en"] },
author: { analyzers: ["identity"] }
}
}
},
primarySort: [
{ field: "createdAt", direction: "desc" }
],
storedValues: [
{ fields: ["title", "author.name"], compression: "lz4" }
]
});
// Create SearchAlias view (Enterprise Edition)
const aliasView = await db.createView("content_search", {
type: "search-alias",
indexes: [
{ collection: "articles", index: "article_text_index" },
{ collection: "blogs", index: "blog_search_index" }
]
});
// Get reference to existing view
const existingView = db.view("article_search");
// List all views
const allViews = await db.views();
console.log(`Found ${allViews.length} views in database`);Retrieve and manage view metadata and configuration.
/**
* View class for managing ArangoSearch and SearchAlias views
*/
class View {
/** View name */
readonly name: string;
/**
* Checks if the view exists
* @returns Promise resolving to boolean indicating existence
*/
exists(): Promise<boolean>;
/**
* Retrieves view information and metadata
* @returns Promise resolving to view description
*/
get(): Promise<ViewDescription>;
/**
* Creates the view with specified options
* @param options - View creation options
* @returns Promise resolving to view description
*/
create(options: CreateViewOptions): Promise<ViewDescription>;
/**
* Gets or sets view properties
* @param properties - Properties to update (optional)
* @returns Promise resolving to current/updated properties
*/
properties(properties?: ViewPropertiesOptions): Promise<ViewProperties>;
/**
* Updates view properties (partial update)
* @param properties - Properties to update
* @returns Promise resolving to updated properties
*/
updateProperties(properties: ViewPropertiesOptions): Promise<ViewProperties>;
/**
* Replaces all view properties
* @param properties - New properties to set
* @returns Promise resolving to new properties
*/
replaceProperties(properties: ViewPropertiesOptions): Promise<ViewProperties>;
/**
* Renames the view
* @param newName - New name for the view
* @returns Promise resolving to updated view description
*/
rename(newName: string): Promise<ViewDescription>;
/**
* Drops (deletes) the view
* @returns Promise resolving when view is dropped
*/
drop(): Promise<void>;
}Usage Examples:
const view = db.view("article_search");
// Check if view exists
if (!(await view.exists())) {
await view.create({
type: "arangosearch",
links: {
articles: {
analyzers: ["text_en"],
fields: { title: {}, content: {} }
}
}
});
}
// Get view information
const info = await view.get();
console.log("View type:", info.type);
console.log("Collections linked:", Object.keys(info.links || {}));
// Update view properties to add new collection
await view.updateProperties({
links: {
...info.links,
news: {
analyzers: ["text_en"],
fields: {
headline: { analyzers: ["text_en"] },
body: { analyzers: ["text_en"] }
}
}
}
});
// Get updated properties
const updatedProps = await view.properties();
console.log("Updated view links:", Object.keys(updatedProps.links || {}));
// Rename view
await view.rename("content_search_v2");
// Eventually drop view
await view.drop();Execute search queries using ArangoSearch views with advanced search features.
Usage Examples:
// Full-text search with ArangoSearch view
const searchResults = await db.query(aql`
FOR doc IN article_search
SEARCH ANALYZER(
PHRASE(doc.title, "machine learning") OR
PHRASE(doc.content, "artificial intelligence"),
"text_en"
)
SORT TFIDF(doc) DESC
LIMIT 10
RETURN {
title: doc.title,
author: doc.author.name,
snippet: LEFT(doc.content, 200),
score: TFIDF(doc)
}
`);
// Advanced search with multiple criteria
const advancedSearch = await db.query(aql`
FOR doc IN article_search
SEARCH (
ANALYZER(PHRASE(doc.title, ${searchTerm}), "text_en") OR
ANALYZER(PHRASE(doc.content, ${searchTerm}), "text_en")
)
AND doc.tags ANY IN ${allowedTags}
AND doc.publishedAt >= ${startDate}
// Boost recent articles
LET boost = doc.publishedAt > DATE_SUBTRACT(DATE_NOW(), 30, "day") ? 2 : 1
SORT TFIDF(doc) * boost DESC, doc.publishedAt DESC
LIMIT ${offset}, ${limit}
RETURN {
id: doc._key,
title: doc.title,
author: doc.author.name,
publishedAt: doc.publishedAt,
tags: doc.tags,
relevanceScore: TFIDF(doc) * boost,
// Use stored values for performance
storedTitle: doc.title,
storedAuthor: doc.author.name
}
`);
// Faceted search with aggregations
const facetedSearch = await db.query(aql`
FOR doc IN article_search
SEARCH ANALYZER(PHRASE(doc.content, ${query}), "text_en")
COLLECT
category = doc.category,
author = doc.author.name
AGGREGATE count = LENGTH()
RETURN {
category,
author,
count
}
`);
// Geospatial search combined with text search
const geoTextSearch = await db.query(aql`
FOR doc IN venue_search
SEARCH (
ANALYZER(PHRASE(doc.name, ${venueName}), "text_en") OR
ANALYZER(PHRASE(doc.description, ${searchText}), "text_en")
)
AND GEO_DISTANCE(doc.location, ${userLocation}) <= ${radiusKm} * 1000
SORT GEO_DISTANCE(doc.location, ${userLocation}) ASC
LIMIT 20
RETURN {
name: doc.name,
description: doc.description,
location: doc.location,
distance: GEO_DISTANCE(doc.location, ${userLocation})
}
`);Advanced search capabilities including custom scoring, highlighting, and real-time indexing.
Usage Examples:
// Custom scoring with multiple factors
const customScoredSearch = await db.query(aql`
FOR doc IN article_search
SEARCH ANALYZER(PHRASE(doc.content, ${searchTerm}), "text_en")
// Custom relevance scoring
LET textScore = TFIDF(doc)
LET recencyScore = (DATE_NOW() - doc.publishedAt) / (1000 * 60 * 60 * 24 * 30) // Age in months
LET popularityScore = LOG10(doc.viewCount + 1)
LET authorScore = doc.author.reputation / 100
LET finalScore = textScore * 0.4 +
(1 / (recencyScore + 1)) * 0.2 +
popularityScore * 0.3 +
authorScore * 0.1
SORT finalScore DESC
LIMIT 20
RETURN {
title: doc.title,
author: doc.author.name,
publishedAt: doc.publishedAt,
viewCount: doc.viewCount,
scores: {
text: textScore,
recency: recencyScore,
popularity: popularityScore,
author: authorScore,
final: finalScore
}
}
`);
// Search with highlighting (requires stored values or re-fetch)
const highlightedSearch = await db.query(aql`
FOR doc IN article_search
SEARCH ANALYZER(PHRASE(doc.content, ${searchTerm}), "text_en")
SORT TFIDF(doc) DESC
LIMIT 10
// Get full document for highlighting
LET fullDoc = DOCUMENT("articles", doc._key)
RETURN {
id: doc._key,
title: fullDoc.title,
content: fullDoc.content,
score: TFIDF(doc),
// Client-side highlighting needed for content
searchTerm: ${searchTerm}
}
`);
// Real-time search with filters
const realtimeSearch = await db.query(aql`
FOR doc IN live_content_search
SEARCH (
ANALYZER(PHRASE(doc.title, ${query}) OR PHRASE(doc.content, ${query}), "text_en")
)
AND doc.status == "published"
AND doc.publishedAt >= ${Date.now() - 24 * 60 * 60 * 1000} // Last 24 hours
// Use primary sort from view definition
SORT doc.publishedAt DESC
LIMIT 50
RETURN {
id: doc._key,
title: doc.title,
publishedAt: doc.publishedAt,
author: doc.author,
summary: LEFT(doc.content, 300)
}
`);
// Multi-language search
const multilingualSearch = await db.query(aql`
FOR doc IN multilingual_search
SEARCH (
ANALYZER(PHRASE(doc.title_en, ${englishQuery}), "text_en") OR
ANALYZER(PHRASE(doc.title_es, ${spanishQuery}), "text_es") OR
ANALYZER(PHRASE(doc.title_fr, ${frenchQuery}), "text_fr")
)
SORT TFIDF(doc) DESC
LIMIT 20
RETURN {
id: doc._key,
titles: {
en: doc.title_en,
es: doc.title_es,
fr: doc.title_fr
},
language: doc.primary_language,
score: TFIDF(doc)
}
`);Optimize view performance and manage index maintenance.
/**
* Gets view optimization statistics
* @returns Promise resolving to optimization stats
*/
getOptimizationStats(): Promise<ViewOptimizationStats>;
/**
* Triggers view optimization/consolidation
* @param options - Optimization options
* @returns Promise resolving when optimization starts
*/
optimize(options?: ViewOptimizationOptions): Promise<void>;
/**
* Gets view indexing progress and statistics
* @returns Promise resolving to indexing stats
*/
getIndexingStats(): Promise<ViewIndexingStats>;Usage Examples:
const view = db.view("large_content_search");
// Check optimization stats
const optimizationStats = await view.getOptimizationStats();
console.log("Segments count:", optimizationStats.segmentsCount);
console.log("Memory usage:", optimizationStats.memoryUsage);
console.log("Last optimization:", optimizationStats.lastOptimization);
if (optimizationStats.segmentsCount > 10) {
// Trigger optimization
await view.optimize({
maxSegments: 5,
waitForCompletion: false
});
console.log("View optimization started");
}
// Monitor indexing progress
const indexingStats = await view.getIndexingStats();
console.log("Documents indexed:", indexingStats.documentsIndexed);
console.log("Indexing progress:", `${indexingStats.progress * 100}%`);
console.log("Index size:", indexingStats.indexSize);
// Performance monitoring query
const performanceMetrics = await db.query(aql`
FOR doc IN article_search
SEARCH ANALYZER(PHRASE(doc.content, "test query"), "text_en")
OPTIONS { profile: true }
LIMIT 1
RETURN doc
`);
console.log("Query execution time:", performanceMetrics.extra.profile.executing);class View {
readonly name: string;
exists(): Promise<boolean>;
get(): Promise<ViewDescription>;
create(options: CreateViewOptions): Promise<ViewDescription>;
properties(properties?: ViewPropertiesOptions): Promise<ViewProperties>;
updateProperties(properties: ViewPropertiesOptions): Promise<ViewProperties>;
replaceProperties(properties: ViewPropertiesOptions): Promise<ViewProperties>;
rename(newName: string): Promise<ViewDescription>;
drop(): Promise<void>;
}
type CreateViewOptions = ArangoSearchViewOptions | SearchAliasViewOptions;
interface ArangoSearchViewOptions {
type: "arangosearch";
links?: Record<string, ArangoSearchViewLinkOptions>;
primarySort?: ArangoSearchViewPrimarySortEntry[];
storedValues?: ArangoSearchViewStoredValueOptions[];
cleanupIntervalStep?: number;
commitIntervalMsec?: number;
consolidationIntervalMsec?: number;
consolidationPolicy?: ArangoSearchViewConsolidationPolicy;
writebufferIdle?: number;
writebufferActive?: number;
writebufferSizeMax?: number;
}
interface SearchAliasViewOptions {
type: "search-alias";
indexes: Array<{
collection: string;
index: string;
}>;
}
interface ArangoSearchViewLinkOptions {
analyzers?: string[];
fields?: Record<string, ArangoSearchViewLinkOptions>;
includeAllFields?: boolean;
storeValues?: "none" | "id";
trackListPositions?: boolean;
cache?: boolean;
}
interface ArangoSearchViewPrimarySortEntry {
field: string;
direction?: Direction;
}
type Direction = "asc" | "desc";
interface ArangoSearchViewStoredValueOptions {
fields: string[];
compression?: Compression;
cache?: boolean;
}
type Compression = "lz4" | "none";
interface ViewDescription {
id: string;
name: string;
type: "arangosearch" | "search-alias";
globallyUniqueId: string;
}
interface ArangoSearchViewDescription extends ViewDescription {
type: "arangosearch";
links: Record<string, ArangoSearchViewLinkOptions>;
primarySort: ArangoSearchViewPrimarySortEntry[];
storedValues: ArangoSearchViewStoredValueOptions[];
cleanupIntervalStep: number;
commitIntervalMsec: number;
consolidationIntervalMsec: number;
consolidationPolicy: ArangoSearchViewConsolidationPolicy;
writebufferIdle: number;
writebufferActive: number;
writebufferSizeMax: number;
}
interface SearchAliasViewDescription extends ViewDescription {
type: "search-alias";
indexes: Array<{
collection: string;
index: string;
}>;
}
type ViewProperties = ArangoSearchViewDescription | SearchAliasViewDescription;
type ViewPropertiesOptions = Partial<ArangoSearchViewOptions> | Partial<SearchAliasViewOptions>;
interface ArangoSearchViewConsolidationPolicy {
type: "tier" | "bytes_accum";
segmentsBytesFloor?: number;
segmentsBytesMax?: number;
segmentsMax?: number;
segmentsMin?: number;
minScore?: number;
}
interface ViewOptimizationStats {
segmentsCount: number;
memoryUsage: number;
lastOptimization: string;
optimizationInProgress: boolean;
}
interface ViewOptimizationOptions {
maxSegments?: number;
waitForCompletion?: boolean;
timeout?: number;
}
interface ViewIndexingStats {
documentsIndexed: number;
totalDocuments: number;
progress: number;
indexSize: number;
lastUpdate: string;
isUpToDate: boolean;
}