Full-Text Search in Frappe v15
What is Full-Text Search?
Full-Text Search (FTS) in Frappe v15 is a database-backed search mechanism that indexes field values of DocTypes and enables fast keyword-based search queries. It supports partial matches, relevance scoring, and result ranking in both the UI (Global Search) and the backend Python API.
Frappe uses MariaDB full-text search capabilities to perform indexed search.
How does Full-Text Search Work in Frappe?
Frappe automatically creates full-text indexes for:
- DocType title fields
- DocType search_fields
- Mandatory text content fields
When a document is saved, Frappe updates its internal Global Search index and allows resolving queries via:
- Desk search bar
- Search endpoint API
- Python search APIs
This ensures fast lookup across thousands of records.
What DocTypes Support Full-Text Search?
All standard DocTypes and custom DocTypes can participate in full-text search if:
- They are not Single records
- They have searchable fields
- They are marked as Indexable
In addition, DocTypes become searchable when:
- title_field is defined
- search_fields is assigned
- custom fields are flagged for search
How to Configure DocType Search Fields?
Step-by-Step Configuration
To make a DocType searchable:
1. Define Title Field
Open DocType → Edit → Title Field
Example:
title_field: item_name
2. Define Search Fields
To control search relevance, add:
search_fields: item_code, item_name, description
This creates additional indexed columns in the search backend.
Format: comma-separated list of fields.
How to Perform Full-Text Search in Code?
Frappe provides a Python API for executing full-text search queries.
The API returns relevant results along with matching DocType and primary key.
Example: Basic Full-Text Search
import frappe
results = frappe.get_all(
"Item",
fields=["name", "item_name"],
filters={"_fulltext": "steel"}
)
This returns Items where indexed text contains the word “steel”.
Example: Search Across Multiple Fields
frappe.get_all(
"Customer",
fields=["name", "customer_name"],
filters={"_fulltext": "Ahmedabad"}
)
The _fulltext filter triggers a full-text search query.
How to Use Full-Text Search from REST API?
You can call search queries over HTTP:
GET /api/resource/Item?_fulltext=steel
You can combine full-text search with filters:
GET /api/resource/Item?_fulltext=steel&filters=[["item_group","=","Raw Material"]]
Global Search vs Full-Text Search
| Feature | Global Search | Full-Text Search API |
| Scope | All searchable DocTypes | Defined DocType only |
| UI | Desk Search Bar | Backend API / Code |
| Ranking | Relevance scoring | Database ranking |
| Use-Case | User search UI | Programmatic search queries |
Both use the same search index, but serve different use-cases.
Reindexing the Search Index
If you add fields, migrate database, or import large data:
bench rebuild-global-search
bench migrate
This regenerates the complete search index for accuracy and performance.
How to Control Search Relevance?
1. Order of fields
Fields defined earlier in search_fields have higher relevance.
Example:
search_fields: item_code, item_name
item_code has more weight.
2. Title field is always top-ranked
title_field has highest priority during matching.
3. Avoid unnecessary fields
Only define fields that represent search identity:
- Name identifiers
- User-facing text
- Descriptions
- Category values
Avoid heavy text fields unless needed.
Supported Field Types
The following text-based types are indexed:
- Data
- Text
- Small Text
- Long Text
- Read Only (if text)
- Link field display field
Binary fields, images, and attachments are not indexed.
Best Practices for Full-Text Search in Frappe
To keep search fast and accurate:
Use specific search_fields
Avoid adding 10+ fields to index.
Optimize large DocTypes
Add only relevant fields for identity search.
Avoid indexing HTML fields
Full text may include unwanted markup.
Rebuild index after migration
Ensures accurate indexing.
Use _fulltext filter
Instead of like queries in code.
Use REST API carefully
Avoid heavy search load in production.
Troubleshooting
Search Does Not Return Results
- Field not included in search index
- _fulltext filter missing
- DocType index not rebuilt
- Search field incorrectly defined
Slow Search
- Too many indexed fields
- Large multi-table queries
- Missing index rebuild after migration
Real-World Use Cases
Full-Text Search is commonly used in:
- ERP dashboards
- Mobile barcode search
- Inventory search
- Sales order lookup
- Customer lookup
- Web storefront product search
- Quick create flows
Applications and portals can embed search logic using the REST API.
Target Audience Tags
- ERP Integration Developers
- Frappe App Developers
- Data Engineers
- ERPNext Consultants
- Frontend Developers (React, Vue, Flutter)
Technical Prerequisites
- Python usage in Frappe
- DocType configuration
- Bench commands
- Basic DB indexing knowledge
Cross-References (Recommended Topics)
To extend knowledge:
- Frappe Search API
- Query Builder
- REST API
- Jinja Templating
- Database API
- Hooks for Indexing
- Background Jobs for Import
- Multi-tenant Architecture & Search