tantivy-py Documentation
repository·master·Indexed 19 days ago
https://github.com/quickwit-oss/tantivy-pyPython bindings for Tantivy, a high-performance full-text search engine library written in Rust. Version 0.26.0. Provides tools for defining schemas via SchemaBuilder, managing indices, and performing searches. Includes detailed API references for Document manipulation, query parsing, and comprehensive error handling for query failures such as FieldDoesNotExistError, ExpectedIntError, and SyntaxError.
What's inside tantivy-py
- tantivy-py is a Python wrapper for the tantivy full-text search engine. Tantivy is a high-performance search engine library inspired by Apache Lucene. Use tantivy-py to integrate advanced full-text search capabilities into your Python applications.
What is a Tantivy Document?
masterA
tantivy.Documentis the primary object used for indexing and searching. Conceptually, a document is an unordered collection of tuples consisting of afield_nameand avalue. A single field can appear multiple times within a document, meaning a field can hold multiple values.You can construct a document in several ways:
- Empty constructor + explicit addition: Create an empty
Document()and useadd_*methods to populate it. - Constructor with field values: Pass field values directly to the
Documentconstructor. You can pass lists of values or single values (syntactic sugar). - From a dictionary: Use
Document.from_dict(py_dict, schema=None)to create a document from a Python dictionary. This is highly recommended when dealing with numeric fields to ensure correct type mapping via the providedschema.
# Method 1: Explicit addition doc = tantivy.Document() doc.add_text("title", "The Old Man and the Sea") # Method 2: Constructor with single values (syntactic sugar) doc = tantivy.Document(title="The Old Man and the Sea", body="...") # Method 3: From dictionary with schema (recommended for numeric types) schema = SchemaBuilder().add_integer_field("signed").build() doc = tantivy.Document.from_dict({"signed": -5}, schema=schema)- Empty constructor + explicit addition: Create an empty
What is a DocAddress?
masterA
DocAddressobject contains the necessary information to uniquely identify a specific document within the context of aSearcher.It consists of two parts:
segment_ord: An integer identifying the specific segment hosting the document. This ordinal is only meaningful when used in the context of aSearcher.doc: The segment-localDocId(an integer) for the document.
Work with Facets for hierarchical data
masterA
Facetrepresents a point in a hierarchy, typically modeled like a filepath (e.g.,/electronics/tv_and_video/led_tv). Documents associated with a facet are implicitly associated with all its ancestor facets.Key operations:
- Creation: Use
Facet.from_string(facet_string)to create a facet from a string orFacet.from_encoded(encoded_bytes)from binary data. The root facet/can be accessed viaFacet.root(). - Hierarchy: Use
is_prefix_of(other_facet)to check ifother_facetis a subfacet of the current one. - Path Manipulation: Use
to_path()to get a list of segments (e.g.,['europe', 'france']) orto_path_str()to get the string representation.
# Create a facet from a string facet = Facet.from_string("/europe/france") # Check hierarchy root = Facet.root() print(facet.is_prefix_of(root)) # Returns True if root is prefix # Get path segments segments = facet.to_path() # ['europe', 'france'] # Get string representation path_str = facet.to_path_str() # "/europe/france"- Creation: Use
Define a Tantivy Schema using SchemaBuilder
masterIn
tantivy-py, theSchemaobject defines the structure of your index. The schema is strictly typed. Because of this strictness, you should not attempt to instantiateSchemadirectly; instead, use theSchemaBuilderclass to construct your schema definition.# Note: Actual usage requires SchemaBuilder as mentioned in the documentation # Example pattern based on documentation description: from tantivy import SchemaBuilder schema_builder = SchemaBuilder() # ... add fields using schema_builder ... schema = schema_builder.build()Use the Tokenizer class to create built-in tokenizers
masterThe
Tokenizerclass provides access to all of Tantivy's built-in tokenizers via static methods. Each method returns a wrapper around a specific Tantivy tokenizer.These tokenizer objects are primarily intended to be passed to a
TextAnalyzerBuilderusing thetokenizer=parameter to define how text should be broken down into tokens during indexing or searching.tokenizer = Tokenizer.regex(r"\w+") # Typically used as: # builder = TextAnalyzerBuilder(tokenizer=tokenizer)How tokenizers and text analyzers work together
masterIn Tantivy-py, there is a distinction between a Tokenizer and a Text Analyzer, though the
IndexAPI uses the term 'tokenizer' to refer to both:- Tokenizer: A component that segments raw text into individual tokens.
- Text Analyzer: A complete pipeline that starts with one
Tokenizerand applies zero or moreFilterobjects (like lowercase or stopword removal) to the tokens.
Important API Note: When using
SchemaBuilder.add_text_field(..., tokenizer_name=...)orIndex.register_tokenizer(...), the parameter expects the name of a Text Analyzer, not just a raw tokenizer.How to build a Tantivy schema using SchemaBuilder
masterTantivy requires a strict schema where you must specify in advance whether a field is indexed, stored, or configured as a fast field. You use the
SchemaBuilderclass to define fields one by one and then finalize the process by calling.build().Key Concepts:
- Stored: If
True, the field's content can be retrieved from aSearcherlater. - Indexed: If
True, the field is indexed for searching. - Fast Fields: A column-oriented storage format designed for fast random access of document fields given a document ID.
- Build Lifecycle: Once
.build()is called, theSchemaBuilderinstance can no longer be used.
>>> builder = tantivy.SchemaBuilder() >>> title = builder.add_text_field("title", stored=True) >>> body = builder.add_text_field("body") >>> schema = builder.build()- Stored: If
Use the Filter class for text analysis
masterThe
Filterclass provides access to all of Tantivy's built-inTokenFilters. These filter objects are designed to be passed to thefilter()method of aTextAnalyzerBuilderinstance to customize how text is processed during indexing or searching.Common use cases include removing stopwords, stemming words, or normalizing text (e.g., converting to lowercase or ASCII folding).
# Example of creating a filter filter = Filter.alpha_num()How segment merging works in tantivy-py
masterWhen you add documents to a
tantivyindex, the data is stored in multiple sections called segments. To maintain index performance, these segments are merged together in background threads.Currently,
tantivy-pyuses theLogMergePolicyas the default merge policy, which is suitable for most use cases. Because merging happens in background threads, you must ensure these processes complete before finishing your indexing task to avoid data inconsistencies or incomplete segments.Ensure background merging threads complete after indexing
masterAfter adding documents and calling
writer.commit(), you must callwriter.wait_merging_threads()to allow background segment merging to finish.Warning: Calling
wait_merging_threads()will consume the writer object, making the identifier no longer usable for further operations. This should be the final step in your indexing workflow.schema = Schema(...) # Define your schema index = Index(schema) writer = index.writer() for ... in data: document = Document(...) # Create your document writer.add_document(document) writer.commit() # Final step: wait for background threads to finish writer.wait_merging_threads()Handle query parsing errors in tantivy-py
masterThe
tantivy.query_parser_errorsubmodule contains all possible errors raised during query parsing. When using lenient parsing methods likeindex.parse_query_lenient(), errors are returned as a list rather than being raised as exceptions. You can inspect this list to identify specific issues such as missing fields or type mismatches.To use these errors, import the
query_parser_errorsubmodule and check the type of the error objects returned by the parser.import tantivy from tantivy import query_parser_error builder = tantivy.SchemaBuilder() title = builder.add_text_field("title", stored=True) body = builder.add_text_field("body") id = builder.add_unsigned_field("id") rating = builder.add_float_field("rating") schema = builder.build() index = tantivy.Index(schema) # parse_query_lenient returns (query, errors) query, errors = index.parse_query_lenient( "bod:'world' AND id:<3.5 AND rating:5.0" ) assert len(errors) == 2 # errors[0] might be a FieldDoesNotExistError # errors[1] might be an ExpectedIntError