Skip to main content

Search Integration

Glean's Search API provides powerful enterprise search capabilities that you can integrate into your applications. Whether you're building a search interface, adding search functionality to existing tools, or creating intelligent agents, Glean's search capabilities can help users find the information they need.

Key Features​

  • Enterprise Search: Search across all your organization's connected data sources
  • Intelligent Ranking: AI-powered relevance scoring and result ranking
  • Faceted Filtering: Filter results by source, type, date, and custom attributes
  • Real-time Results: Fast search with sub-second response times
  • Permission Awareness: Results respect user permissions and data access controls

Getting Started​

Common Use Cases​

Build a search interface for your internal documentation, wikis, and knowledge repositories.

Search through your organization's source code, documentation, and development resources.

Document Discovery​

Help users find relevant documents, presentations, and files across all connected systems.

Expert Finding​

Locate subject matter experts and colleagues with specific knowledge or experience.

Search Patterns​

Simple text-based search across all available content:

import requests
import os

api_token = os.getenv("GLEAN_API_TOKEN")
server_url = os.getenv("GLEAN_SERVER_URL")
base_url = f"{server_url}/rest/api/v1"

headers = {
"Authorization": f"Bearer {api_token}",
"Content-Type": "application/json"
}

response = requests.post(
f"{base_url}/search",
headers=headers,
json={
"query": "vacation policy",
"pageSize": 10
}
)
response.raise_for_status()

results = response.json().get("results", [])
for result in results:
print(f"Title: {result.get('title', 'No title')}")
print(f"URL: {result.get('url', 'No URL')}")
snippets = result.get('snippets', [])
if snippets:
print(f"Snippet: {snippets[0].get('snippet', '')}")

Search with specific filters to narrow results:

from glean.api_client import Glean, models

with Glean(api_token=api_token, server_url=server_url) as glean:
response = glean.client.search.query(
query="quarterly results",
page_size=10,
request_options=models.SearchRequestOptions(
facet_bucket_size=10,
facet_filters=[
models.FacetFilter(
field_name="app",
values=[
models.FacetFilterValue(
value="confluence",
relation_type=models.RelationType.EQUALS,
),
models.FacetFilterValue(
value="sharepoint",
relation_type=models.RelationType.EQUALS,
),
],
),
models.FacetFilter(
field_name="type",
values=[
models.FacetFilterValue(
value="document",
relation_type=models.RelationType.EQUALS,
),
],
),
],
),
)

Search with Date Filters​

Find recent or time-specific content:

from datetime import datetime, timedelta
from glean.api_client import Glean, models

last_month = (datetime.now() - timedelta(days=30)).strftime("%Y-%m-%d")

with Glean(api_token=api_token, server_url=server_url) as glean:
response = glean.client.search.query(
query="product updates",
request_options=models.SearchRequestOptions(
facet_bucket_size=10,
facet_filters=[
models.FacetFilter(
field_name="last_updated_at",
values=[
models.FacetFilterValue(
value=last_month,
relation_type=models.RelationType.GT,
),
],
),
],
),
)

See Filtering Results for the full set of last_updated_at values, including special ranges like today and past_week.

Advanced Features​

Implement search suggestions and autocomplete:

with Glean(api_token=api_token, server_url=server_url) as glean:
autocomplete_response = glean.client.search.autocomplete(
query="vacat",
result_size=5,
)

for r in autocomplete_response.results or []:
print(f"Suggestion: {r.result}")

Search Analytics​

Track search performance and user behavior:

from glean.api_client import Glean, models

with Glean(api_token=api_token, server_url=server_url) as glean:
response = glean.client.search.query(query="benefits")

# Each response and each result carries a trackingToken; report result
# events back via /feedback to improve ranking quality.
clicked_result = response.results[0]
glean.client.activity.feedback(feedback1={
"tracking_tokens": [clicked_result.tracking_token],
"event": models.FeedbackEvent.CLICK,
})

Search across multiple instances or systems:

def federated_search(query: str):
# Search primary instance
with Glean(api_token=primary_token, server_url=primary_url) as glean:
primary_results = glean.client.search.query(query=query)

# Search secondary instance
with Glean(api_token=secondary_token, server_url=secondary_url) as glean:
secondary_results = glean.client.search.query(query=query)

# Combine result lists; each list arrives ranked by Glean already
return (primary_results.results or []) + (secondary_results.results or [])

Building Search Interfaces​

React Search Component​

import { useState } from 'react';
import { Glean } from '@gleanwork/api-client';

type SearchResult = {
url: string;
title?: string;
snippets?: Array<{ snippet?: string }>;
};

const SearchComponent = () => {
const [query, setQuery] = useState('');
const [results, setResults] = useState<SearchResult[]>([]);
const [loading, setLoading] = useState(false);

const client = new Glean({
apiToken: process.env.REACT_APP_GLEAN_TOKEN ?? '',
serverURL: process.env.REACT_APP_GLEAN_SERVER_URL,
});

const handleSearch = async (searchQuery: string) => {
if (!searchQuery.trim()) return;

setLoading(true);
try {
const response = await client.client.search.query({
query: searchQuery,
pageSize: 20,
});
setResults(response.results || []);
} catch (error) {
console.error('Search error:', error);
} finally {
setLoading(false);
}
};

return (
<div>
<input
type="text"
value={query}
onChange={(e) => setQuery(e.target.value)}
onKeyDown={(e) => e.key === 'Enter' && handleSearch(query)}
placeholder="Search your organization's knowledge..."
/>

{loading && <div>Searching...</div>}

<div>
{results.map((result, index) => (
<div key={index} className="search-result">
<h3>
<a href={result.url}>{result.title}</a>
</h3>
<p>{result.snippets?.[0]?.snippet}</p>
</div>
))}
</div>
</div>
);
};

Search with Filters UI​

const FilteredSearchComponent = () => {
const [filters, setFilters] = useState({
datasources: [],
dateRange: null,
objectTypes: []
});

const applyFilters = async (query: string) => {
const facetFilters = [];

if (filters.datasources.length > 0) {
facetFilters.push({
fieldName: "app",
values: filters.datasources.map((d) => ({
value: d,
relationType: "EQUALS",
})),
});
}

if (filters.objectTypes.length > 0) {
facetFilters.push({
fieldName: "type",
values: filters.objectTypes.map((t) => ({
value: t,
relationType: "EQUALS",
})),
});
}

const response = await client.client.search.query({
query,
requestOptions: { facetBucketSize: 10, facetFilters },
});

return response.results;
};

// UI implementation...
};

Performance Optimization​

Caching Search Results​

import hashlib
import time

class CachedSearchClient:
def __init__(self, client: Glean):
self.client = client
self._cache = {}

def _cache_key(self, query: str) -> str:
return hashlib.md5(query.encode()).hexdigest()

def search(self, query: str, cache_ttl: int = 300):
cache_key = self._cache_key(query)

if cache_key in self._cache:
cached_result, timestamp = self._cache[cache_key]
if time.time() - timestamp < cache_ttl:
return cached_result

result = self.client.client.search.query(query=query)

self._cache[cache_key] = (result, time.time())
return result

Pagination and Infinite Scroll​

def paginated_search(glean, query: str, page_size: int = 20):
cursor = None
all_results = []

while True:
response = glean.client.search.query(
query=query,
page_size=page_size,
cursor=cursor,
)
all_results.extend(response.results or [])

if not response.has_more_results:
break

cursor = response.cursor

return all_results

Error Handling​

import time

from glean.api_client import Glean, errors

def robust_search(glean, query: str, max_retries: int = 3):
for attempt in range(max_retries):
try:
return glean.client.search.query(query=query)
except errors.GleanError as e:
if e.status_code == 429: # Rate limited
time.sleep(2 ** attempt)
continue
elif e.status_code >= 500: # Server error
if attempt < max_retries - 1:
time.sleep(1)
continue
raise e

raise Exception(f"Search failed after {max_retries} attempts")

Next Steps​

  1. Explore Examples: Check out specific filtering and search examples
  2. Try the API: Test search queries in your environment
  3. Build Interfaces: Create search UIs for your applications
  4. Optimize: Implement caching and performance improvements