or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

company-management.mdevent-tracking.mdindex.mdjob-management.mdquery-autocompletion.mdsearch-filtering.mdtenant-management.md

query-autocompletion.mddocs/

0

# Query Autocompletion

1

2

Query autocompletion and suggestion functionality for building intelligent search interfaces with support for job titles, companies, and location-based suggestions. The completion service provides real-time query suggestions to improve user search experience and help users discover relevant job opportunities.

3

4

## Capabilities

5

6

### Query Completion

7

8

Provides intelligent autocompletion suggestions for job search queries based on job titles, company names, skills, and locations within the tenant's job dataset.

9

10

```python { .api }

11

def complete_query(self, tenant: str, query: str, page_size: int = None,

12

language_codes: List[str] = None, company: str = None,

13

scope: CompletionScope = None, type_: CompletionType = None) -> CompleteQueryResponse:

14

"""

15

Returns autocomplete suggestions for job search queries.

16

17

Parameters:

18

- tenant (str): Tenant resource name for scoped suggestions

19

- query (str): Partial query string to complete (required, max 255 chars)

20

- page_size (int): Maximum number of suggestions to return (max 100, default 10)

21

- language_codes (List[str]): Preferred languages for suggestions (ISO 639-1 codes)

22

- company (str): Company resource name to scope suggestions

23

- scope (CompletionScope): Scope of completion suggestions

24

- type_ (CompletionType): Type of completion to perform

25

26

Returns:

27

CompleteQueryResponse: Completion suggestions with metadata

28

29

Raises:

30

- InvalidArgument: Invalid query string or parameters

31

- PermissionDenied: Insufficient permissions for completion requests

32

"""

33

```

34

35

**Usage Example:**

36

37

```python

38

from google.cloud.talent import CompletionClient, CompletionScope, CompletionType

39

40

client = CompletionClient()

41

42

# Basic query completion

43

response = client.complete_query(

44

tenant="projects/my-project/tenants/my-tenant",

45

query="software eng",

46

page_size=10

47

)

48

49

for completion in response.completion_results:

50

print(f"Suggestion: {completion.suggestion}")

51

print(f"Type: {completion.type_}")

52

```

53

54

## Completion Configuration

55

56

### Completion Scope

57

58

Controls the scope of suggestions to provide targeted autocompletion.

59

60

```python { .api }

61

class CompletionScope(Enum):

62

"""Scope options for completion suggestions."""

63

COMPLETION_SCOPE_UNSPECIFIED = 0

64

TENANT = 1 # Suggestions from tenant's job data

65

PUBLIC = 2 # Suggestions from public job market data

66

```

67

68

### Completion Type

69

70

Specifies the type of completion to perform for different use cases.

71

72

```python { .api }

73

class CompletionType(Enum):

74

"""Types of completion suggestions."""

75

COMPLETION_TYPE_UNSPECIFIED = 0

76

JOB_TITLE = 1 # Job title completions

77

COMPANY_NAME = 2 # Company name completions

78

COMBINED = 3 # Combined job title and company suggestions

79

```

80

81

**Usage Examples:**

82

83

```python

84

# Job title specific completions

85

title_response = client.complete_query(

86

tenant="projects/my-project/tenants/my-tenant",

87

query="data sci",

88

type_=CompletionType.JOB_TITLE,

89

page_size=15

90

)

91

92

# Company name completions

93

company_response = client.complete_query(

94

tenant="projects/my-project/tenants/my-tenant",

95

query="goog",

96

type_=CompletionType.COMPANY_NAME,

97

page_size=10

98

)

99

100

# Combined suggestions for general search

101

combined_response = client.complete_query(

102

tenant="projects/my-project/tenants/my-tenant",

103

query="python",

104

type_=CompletionType.COMBINED,

105

scope=CompletionScope.TENANT,

106

page_size=20

107

)

108

```

109

110

### Language-Specific Completions

111

112

Request completions in specific languages for internationalized applications.

113

114

```python

115

# Multi-language completion support

116

multilingual_response = client.complete_query(

117

tenant="projects/my-project/tenants/my-tenant",

118

query="desarrollador", # Spanish for "developer"

119

language_codes=["es", "en"], # Spanish and English

120

page_size=10

121

)

122

123

# English-only completions

124

english_response = client.complete_query(

125

tenant="projects/my-project/tenants/my-tenant",

126

query="engineer",

127

language_codes=["en"],

128

page_size=15

129

)

130

```

131

132

### Company-Scoped Completions

133

134

Scope completions to specific companies for targeted job searches.

135

136

```python

137

# Completions scoped to specific company

138

company_scoped_response = client.complete_query(

139

tenant="projects/my-project/tenants/my-tenant",

140

query="software",

141

company="projects/my-project/tenants/my-tenant/companies/google",

142

page_size=10

143

)

144

145

for completion in company_scoped_response.completion_results:

146

print(f"Job at Google: {completion.suggestion}")

147

```

148

149

## Response Structure

150

151

### Completion Response

152

153

```python { .api }

154

class CompleteQueryResponse:

155

"""Response containing completion suggestions and metadata."""

156

completion_results: List[CompletionResult] = None # List of suggestions

157

metadata: ResponseMetadata = None # Response metadata

158

159

class CompletionResult:

160

"""Individual completion suggestion with metadata."""

161

suggestion: str = None # Completed query suggestion

162

type_: CompletionType = None # Type of suggestion

163

image_uri: str = None # Associated image (for company suggestions)

164

```

165

166

**Response Processing:**

167

168

```python

169

response = client.complete_query(

170

tenant="projects/my-project/tenants/my-tenant",

171

query="java dev",

172

type_=CompletionType.COMBINED

173

)

174

175

print(f"Found {len(response.completion_results)} suggestions:")

176

177

for result in response.completion_results:

178

print(f" {result.suggestion} ({result.type_})")

179

180

if result.image_uri:

181

print(f" Logo: {result.image_uri}")

182

```

183

184

## Request and Response Types

185

186

### Completion Service Requests

187

188

```python { .api }

189

class CompleteQueryRequest:

190

tenant: str = None # Tenant resource name (required)

191

query: str = None # Partial query to complete (required, max 255 chars)

192

language_codes: List[str] = None # Preferred languages (ISO 639-1)

193

page_size: int = None # Max suggestions to return (max 100, default 10)

194

company: str = None # Company resource name for scoping

195

scope: CompletionScope = None # Completion scope

196

type_: CompletionType = None # Completion type

197

```

198

199

## Integration Patterns

200

201

### Real-Time Search Interface

202

203

Implement debounced autocompletion for responsive search interfaces.

204

205

```python

206

import asyncio

207

import time

208

from typing import List, Optional

209

210

class SearchAutocompletion:

211

def __init__(self, tenant_name: str, debounce_ms: int = 300):

212

self.tenant_name = tenant_name

213

self.client = CompletionClient()

214

self.debounce_ms = debounce_ms

215

self.last_query_time = 0

216

self.current_task = None

217

218

async def get_suggestions(self, query: str, max_suggestions: int = 10) -> List[str]:

219

"""Get suggestions with debouncing for real-time search."""

220

if len(query.strip()) < 2:

221

return []

222

223

# Cancel previous request if still pending

224

if self.current_task and not self.current_task.done():

225

self.current_task.cancel()

226

227

# Debounce rapid queries

228

self.last_query_time = time.time()

229

await asyncio.sleep(self.debounce_ms / 1000.0)

230

231

# Check if a newer query was made during debounce period

232

if time.time() - self.last_query_time < (self.debounce_ms / 1000.0):

233

return []

234

235

# Make completion request

236

self.current_task = asyncio.create_task(

237

self._fetch_completions(query, max_suggestions)

238

)

239

240

try:

241

return await self.current_task

242

except asyncio.CancelledError:

243

return []

244

245

async def _fetch_completions(self, query: str, max_suggestions: int) -> List[str]:

246

"""Fetch completions from API."""

247

try:

248

response = self.client.complete_query(

249

tenant=self.tenant_name,

250

query=query,

251

type_=CompletionType.COMBINED,

252

page_size=max_suggestions

253

)

254

255

return [result.suggestion for result in response.completion_results]

256

257

except Exception as e:

258

print(f"Completion request failed: {e}")

259

return []

260

261

# Usage in web application

262

autocomplete = SearchAutocompletion("projects/my-project/tenants/my-tenant")

263

264

# In request handler

265

async def handle_autocomplete_request(query: str):

266

suggestions = await autocomplete.get_suggestions(query)

267

return {"suggestions": suggestions}

268

```

269

270

### Cached Completion Service

271

272

Implement caching for frequently requested completions to improve performance.

273

274

```python

275

import time

276

from typing import Dict, Tuple, List

277

from dataclasses import dataclass

278

279

@dataclass

280

class CachedCompletion:

281

suggestions: List[str]

282

timestamp: float

283

ttl_seconds: int = 300 # 5 minutes default TTL

284

285

class CompletionCache:

286

def __init__(self, tenant_name: str, cache_ttl: int = 300):

287

self.tenant_name = tenant_name

288

self.client = CompletionClient()

289

self.cache: Dict[str, CachedCompletion] = {}

290

self.default_ttl = cache_ttl

291

292

def get_completions(self, query: str, max_suggestions: int = 10) -> List[str]:

293

"""Get completions with caching."""

294

cache_key = f"{query.lower()}:{max_suggestions}"

295

296

# Check cache first

297

if cache_key in self.cache:

298

cached = self.cache[cache_key]

299

if time.time() - cached.timestamp < cached.ttl_seconds:

300

return cached.suggestions

301

else:

302

del self.cache[cache_key] # Remove expired entry

303

304

# Fetch from API

305

try:

306

response = self.client.complete_query(

307

tenant=self.tenant_name,

308

query=query,

309

type_=CompletionType.COMBINED,

310

page_size=max_suggestions

311

)

312

313

suggestions = [result.suggestion for result in response.completion_results]

314

315

# Cache the results

316

self.cache[cache_key] = CachedCompletion(

317

suggestions=suggestions,

318

timestamp=time.time(),

319

ttl_seconds=self.default_ttl

320

)

321

322

return suggestions

323

324

except Exception as e:

325

print(f"Completion request failed: {e}")

326

return []

327

328

def clear_cache(self):

329

"""Clear all cached completions."""

330

self.cache.clear()

331

332

def clear_expired(self):

333

"""Remove expired cache entries."""

334

current_time = time.time()

335

expired_keys = [

336

key for key, cached in self.cache.items()

337

if current_time - cached.timestamp >= cached.ttl_seconds

338

]

339

340

for key in expired_keys:

341

del self.cache[key]

342

343

# Usage

344

completion_cache = CompletionCache("projects/my-project/tenants/my-tenant")

345

346

def get_search_suggestions(query: str) -> List[str]:

347

return completion_cache.get_completions(query, max_suggestions=15)

348

```

349

350

### Frontend Integration

351

352

JavaScript/TypeScript integration for web applications.

353

354

```javascript

355

class TalentAutocompletion {

356

constructor(tenantPath, apiEndpoint) {

357

this.tenantPath = tenantPath;

358

this.apiEndpoint = apiEndpoint;

359

this.debounceTimer = null;

360

this.currentController = null;

361

}

362

363

async getSuggestions(query, options = {}) {

364

// Clear previous debounce timer

365

if (this.debounceTimer) {

366

clearTimeout(this.debounceTimer);

367

}

368

369

// Cancel previous request

370

if (this.currentController) {

371

this.currentController.abort();

372

}

373

374

return new Promise((resolve, reject) => {

375

this.debounceTimer = setTimeout(async () => {

376

try {

377

this.currentController = new AbortController();

378

379

const params = new URLSearchParams({

380

tenant: this.tenantPath,

381

query: query,

382

page_size: options.maxSuggestions || 10,

383

type: options.type || 'COMBINED'

384

});

385

386

if (options.languageCodes) {

387

params.append('language_codes', options.languageCodes.join(','));

388

}

389

390

const response = await fetch(

391

`${this.apiEndpoint}/completion?${params}`,

392

{

393

signal: this.currentController.signal,

394

headers: {

395

'Authorization': `Bearer ${await this.getAuthToken()}`

396

}

397

}

398

);

399

400

if (!response.ok) {

401

throw new Error(`Completion request failed: ${response.status}`);

402

}

403

404

const data = await response.json();

405

resolve(data.completion_results || []);

406

407

} catch (error) {

408

if (error.name !== 'AbortError') {

409

reject(error);

410

}

411

}

412

}, options.debounceMs || 300);

413

});

414

}

415

416

async getAuthToken() {

417

// Implement your authentication token retrieval

418

return localStorage.getItem('auth_token');

419

}

420

}

421

422

// Usage in React component

423

const useJobSearchAutocompletion = (tenantPath) => {

424

const [suggestions, setSuggestions] = useState([]);

425

const [loading, setLoading] = useState(false);

426

const autocompletion = useRef(

427

new TalentAutocompletion(tenantPath, '/api/talent')

428

).current;

429

430

const getSuggestions = useCallback(async (query) => {

431

if (query.length < 2) {

432

setSuggestions([]);

433

return;

434

}

435

436

setLoading(true);

437

try {

438

const results = await autocompletion.getSuggestions(query, {

439

maxSuggestions: 10,

440

type: 'COMBINED'

441

});

442

setSuggestions(results.map(r => r.suggestion));

443

} catch (error) {

444

console.error('Autocompletion failed:', error);

445

setSuggestions([]);

446

} finally {

447

setLoading(false);

448

}

449

}, [autocompletion]);

450

451

return { suggestions, loading, getSuggestions };

452

};

453

```

454

455

## Error Handling

456

457

Completion operations can raise several types of exceptions:

458

459

```python

460

from google.api_core import exceptions

461

462

def safe_get_completions(client: CompletionClient, tenant: str, query: str) -> List[str]:

463

"""Safely get completions with comprehensive error handling."""

464

try:

465

response = client.complete_query(tenant=tenant, query=query)

466

return [result.suggestion for result in response.completion_results]

467

468

except exceptions.InvalidArgument as e:

469

print(f"Invalid completion query: {e}")

470

return [] # Return empty list for invalid queries

471

472

except exceptions.PermissionDenied as e:

473

print(f"Completion access denied: {e}")

474

return [] # Return empty list if no permission

475

476

except exceptions.ResourceExhausted as e:

477

print(f"Completion quota exceeded: {e}")

478

return [] # Return empty list if quota exceeded

479

480

except exceptions.DeadlineExceeded as e:

481

print(f"Completion request timeout: {e}")

482

return [] # Return empty list on timeout

483

484

except Exception as e:

485

print(f"Unexpected completion error: {e}")

486

return [] # Never break user experience for completion failures

487

```

488

489

Common error scenarios:

490

- **InvalidArgument**: Empty query, query too long, invalid parameters

491

- **PermissionDenied**: Insufficient IAM permissions for completion requests

492

- **ResourceExhausted**: Completion API quota limits exceeded

493

- **DeadlineExceeded**: Completion request timeout

494

495

## Best Practices

496

497

1. **Query Length**: Only request completions for queries with 2+ characters to avoid noise

498

2. **Debouncing**: Implement debouncing (200-300ms) to avoid excessive API requests during typing

499

3. **Caching**: Cache frequent completions locally to improve performance and reduce API calls

500

4. **Error Handling**: Gracefully handle failures without breaking the search experience

501

5. **Performance**: Limit suggestion counts (5-15) for optimal user experience

502

6. **Cancellation**: Cancel previous requests when new queries are made

503

7. **Accessibility**: Ensure autocompletion interfaces are keyboard and screen reader accessible

504

8. **Analytics**: Track completion usage to optimize suggestion quality and performance

505

506

## Performance Optimization

507

508

### Request Optimization

509

510

```python

511

# Optimize completion requests for performance

512

def optimized_completion_request(query: str) -> CompleteQueryRequest:

513

return CompleteQueryRequest(

514

tenant="projects/my-project/tenants/my-tenant",

515

query=query,

516

page_size=8, # Smaller page size for faster response

517

type_=CompletionType.COMBINED, # Most useful for general search

518

scope=CompletionScope.TENANT # Faster than public scope

519

)

520

```

521

522

### Monitoring and Analytics

523

524

```python

525

import time

526

from collections import defaultdict

527

528

class CompletionAnalytics:

529

def __init__(self):

530

self.request_counts = defaultdict(int)

531

self.response_times = []

532

self.error_counts = defaultdict(int)

533

534

def track_request(self, query: str, response_time: float, success: bool, error_type: str = None):

535

"""Track completion request metrics."""

536

self.request_counts[query] += 1

537

self.response_times.append(response_time)

538

539

if not success and error_type:

540

self.error_counts[error_type] += 1

541

542

def get_metrics(self):

543

"""Get completion performance metrics."""

544

if not self.response_times:

545

return {}

546

547

return {

548

'total_requests': sum(self.request_counts.values()),

549

'unique_queries': len(self.request_counts),

550

'avg_response_time': sum(self.response_times) / len(self.response_times),

551

'error_rate': sum(self.error_counts.values()) / sum(self.request_counts.values()),

552

'most_common_queries': sorted(

553

self.request_counts.items(),

554

key=lambda x: x[1],

555

reverse=True

556

)[:10]

557

}

558

```