feat(search): Improve search functionality: update documentation, refine Lucene query transformation, and add advanced search tests
This commit is contained in:
65
readme.md
65
readme.md
@@ -189,48 +189,42 @@ await user.delete(); // Delete the user from the database
|
||||
|
||||
### Search Functionality
|
||||
|
||||
SmartData provides powerful search capabilities with a Lucene-like query syntax and robust fallback mechanisms:
|
||||
SmartData provides powerful, Lucene‑style search capabilities with robust fallback mechanisms:
|
||||
|
||||
```typescript
|
||||
// Define a model with searchable fields
|
||||
@Collection(() => db)
|
||||
class Product extends SmartDataDbDoc<Product, Product> {
|
||||
@unI()
|
||||
public id: string = 'product-id';
|
||||
|
||||
@svDb()
|
||||
@searchable() // Mark this field as searchable
|
||||
public name: string;
|
||||
|
||||
@svDb()
|
||||
@searchable() // Mark this field as searchable
|
||||
public description: string;
|
||||
|
||||
@svDb()
|
||||
@searchable() // Mark this field as searchable
|
||||
public category: string;
|
||||
|
||||
@svDb()
|
||||
public price: number;
|
||||
@unI() public id: string = 'product-id';
|
||||
@svDb() @searchable() public name: string;
|
||||
@svDb() @searchable() public description: string;
|
||||
@svDb() @searchable() public category: string;
|
||||
@svDb() public price: number;
|
||||
}
|
||||
|
||||
// Get all fields marked as searchable for a class
|
||||
const searchableFields = getSearchableFields('Product'); // ['name', 'description', 'category']
|
||||
// List searchable fields
|
||||
const searchableFields = getSearchableFields('Product');
|
||||
|
||||
// Basic search across all searchable fields
|
||||
const iphoneProducts = await Product.search('iPhone');
|
||||
// 1: Exact phrase across all fields
|
||||
await Product.search('"Kindle Paperwhite"');
|
||||
|
||||
// Field-specific exact match
|
||||
const electronicsProducts = await Product.search('category:Electronics');
|
||||
// 2: Wildcard search across all fields
|
||||
await Product.search('Air*');
|
||||
|
||||
// Partial word search (regex across all fields)
|
||||
const laptopResults = await Product.search('laptop');
|
||||
// 3: Field‑scoped wildcard
|
||||
await Product.search('name:Air*');
|
||||
|
||||
// Multi-word literal search
|
||||
const paperwhite = await Product.search('Kindle Paperwhite');
|
||||
// 4: Boolean AND/OR/NOT
|
||||
await Product.search('category:Electronics AND name:iPhone');
|
||||
|
||||
// Empty query returns all documents
|
||||
const allProducts = await Product.search('');
|
||||
// 5: Grouping with parentheses
|
||||
await Product.search('(Furniture OR Electronics) AND Chair');
|
||||
|
||||
// 6: Multi‑term unquoted (terms AND’d across fields)
|
||||
await Product.search('TypeScript Aufgabe');
|
||||
|
||||
// 7: Empty query returns all documents
|
||||
await Product.search('');
|
||||
```
|
||||
|
||||
The search functionality includes:
|
||||
@@ -238,11 +232,14 @@ The search functionality includes:
|
||||
- `@searchable()` decorator for marking fields as searchable
|
||||
- `getSearchableFields()` to list searchable fields for a model
|
||||
- `search(query: string)` method supporting:
|
||||
- Field-specific exact matches (`field:value`)
|
||||
- Case-insensitive partial matches across all searchable fields
|
||||
- Multi-word literal matching
|
||||
- Exact phrase matches (`"my exact string"` or `'my exact string'`)
|
||||
- Field‑scoped exact & wildcard searches (`field:value`, `field:Air*`)
|
||||
- Wildcard searches across all fields (`Air*`, `?Pods`)
|
||||
- Boolean operators (`AND`, `OR`, `NOT`) with grouping (`(...)`)
|
||||
- Multi‑term unquoted queries AND’d across fields (`TypeScript Aufgabe`)
|
||||
- Single/multi‑term regex searches across fields
|
||||
- Empty queries returning all documents
|
||||
- Automatic escaping of special characters to prevent regex injection
|
||||
- Automatic escaping & wildcard conversion to prevent regex injection
|
||||
|
||||
### EasyStore
|
||||
|
||||
|
Reference in New Issue
Block a user