{"id":4406,"library":"whoosh","title":"Whoosh","description":"Whoosh is a fast, pure-Python library for full-text indexing, searching, and spell checking. It allows developers to add search functionality to applications and websites without external compilers or binary dependencies. The library is highly customizable and currently stable at version 2.7.4, maintained by the whoosh-community.","status":"active","version":"2.7.4","language":"python","source_language":"en","source_url":"https://github.com/whoosh-community/whoosh","tags":["search engine","full-text search","indexing","pure-python","information retrieval"],"install":[{"cmd":"pip install whoosh","lang":"bash","label":"Install stable version"}],"dependencies":[],"imports":[{"symbol":"create_in","correct":"from whoosh.index import create_in"},{"symbol":"Schema","correct":"from whoosh.fields import Schema, TEXT, ID, STORED"},{"symbol":"QueryParser","correct":"from whoosh.qparser import QueryParser"},{"note":"While 'import whoosh.index' works, direct import from whoosh.index is more common for specific functions like create_in or open_dir, and 'from whoosh import index' is used to access general index-related functions and objects.","wrong":"import whoosh.index","symbol":"index","correct":"from whoosh import index"}],"quickstart":{"code":"import os\nfrom whoosh.index import create_in, open_dir\nfrom whoosh.fields import Schema, TEXT, ID\nfrom whoosh.qparser import QueryParser\n\n# 1. Define schema\nschema = Schema(title=TEXT(stored=True), path=ID(stored=True), content=TEXT)\n\n# 2. Create or open index directory\nindexdir = \"indexdir\"\nif not os.path.exists(indexdir):\n    os.mkdir(indexdir)\n    ix = create_in(indexdir, schema)\nelse:\n    ix = open_dir(indexdir)\n\n# 3. Add documents\nwriter = ix.writer()\nwriter.add_document(title=u\"First document\", path=u\"/a\",\n                    content=u\"This is the first document we've added!\")\nwriter.add_document(title=u\"Second document\", path=u\"/b\",\n                    content=u\"The second one is even more interesting!\")\nwriter.commit()\n\n# 4. Search documents\nwith ix.searcher() as searcher:\n    query_parser = QueryParser(\"content\", ix.schema)\n    query = query_parser.parse(\"first\")\n    results = searcher.search(query)\n    for hit in results:\n        print(f\"Found: {hit['title']} at {hit['path']}\")\n\n# Clean up (optional: remove the index directory)\n# import shutil\n# shutil.rmtree(indexdir)\n","lang":"python","description":"This quickstart demonstrates how to define a schema, create or open an index, add documents to the index, and then perform a basic text search. It includes handling the creation of the index directory if it doesn't exist. Documents are added with `title`, `path`, and `content` fields, and a `QueryParser` is used to search the 'content' field."},"warnings":[{"fix":"Prefix string literals with 'u' in Python 2 (e.g., `u'your string'`). In Python 3, all strings are Unicode by default, so `\"your string\"` is sufficient.","message":"When adding documents, ensure text fields are passed as Unicode strings (e.g., `u\"my text\"` in Python 2 or regular strings in Python 3). Non-text fields that are stored but not indexed (STORED type) can be any pickle-able object.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Define a unique field in your Schema (e.g., `path=ID(unique=True)`), then use `writer.update_document()` instead of `writer.add_document()` when you intend to replace or update an existing document. If no match is found for the unique field, `update_document` acts like `add_document`.","message":"Whoosh does not inherently enforce uniqueness for documents. Calling `add_document` multiple times with identical data will result in multiple duplicate documents in the index. Use `update_document` with a `unique=True` field in your schema to overwrite existing documents.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Always ensure the directory for your index exists by creating it with `os.makedirs(indexdir, exist_ok=True)` or `os.mkdir(indexdir)` before calling `create_in()`.","message":"The `whoosh.index.create_in()` function requires the directory to exist before it's called. If the directory does not exist, a `FileNotFoundError` will occur.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Stick to high-level functions like `whoosh.index.create_in()` and `whoosh.index.open_dir()` for managing your index to ensure compatibility and stability.","message":"Direct manipulation of index files or relying on undocumented internal structures can lead to issues with future updates. Always use the public API for index management. Some older examples might show direct `FileStorage` usage without `index.create_in` or `index.open_dir` convenience functions.","severity":"deprecated","affected_versions":"<2.x (informal deprecation, more of a best practice)"}],"env_vars":null,"search_vec":"'2.7.4':46 'add':23 'allow':20 'applic':27 'binari':34 'check':18 'communiti':52 'compil':32 'current':42 'customiz':40 'depend':35 'develop':21 'engin':54 'extern':31 'fast':5 'full':12,56 'full-text':11,55 'function':25 'high':39 'index':14,59 'inform':63 'librari':9,37 'maintain':47 'pure':7,61 'pure-python':6,60 'python':8,62 'retriev':64 'search':15,24,53,58 'spell':17 'stabl':43 'text':13,57 'version':45 'websit':29 'whoosh':1,2,51 'whoosh-commun':50 'without':30","created_at":"2026-04-12T08:54:24.116081+00:00","updated_at":"2026-04-17T00:40:06.341071+00:00","problems":[{"fix":"Ensure `IndexWriter` objects are always closed using a `with` statement. If a stale lock persists, it might need to be manually deleted (e.g., `os.remove('path/to/index/MAIN_WRITELOCK')`).\n\n```python\n# Correct usage using a 'with' statement\nwith ix.writer() as writer:\n    writer.add_document(title='Example', content='Document content')\n\n# Or, for explicit control\nwriter = ix.writer()\ntry:\n    writer.add_document(title='Example', content='Document content')\n    writer.commit()\nfinally:\n    writer.close()\n```","cause":"An `IndexWriter` object was not properly closed, or multiple processes/threads are attempting to write to the index simultaneously, leaving a stale lock file.","error":"whoosh.index.AlreadyLockedError: Locked by '<pid>'"},{"fix":"Import the class from its correct submodule, for example, `Schema` from `whoosh.fields`, `create_in` from `whoosh.index`, and `QueryParser` from `whoosh.qparser`.\n\n```python\nfrom whoosh.fields import Schema, TEXT, ID\nfrom whoosh.index import create_in, open_dir\nfrom whoosh.qparser import QueryParser\n```","cause":"The `Schema` class (and many other core Whoosh components like `create_in`, `QueryParser`) is not directly available under the top-level `whoosh` module; it resides in a specific submodule.","error":"AttributeError: module 'whoosh' has no attribute 'Schema'"},{"fix":"Ensure the index directory exists before attempting to create or open an index, creating it if necessary.\n\n```python\nimport os\nfrom whoosh.index import create_in\nfrom whoosh.fields import Schema, TEXT\n\nindex_dir = \"my_whoosh_index\"\nif not os.path.exists(index_dir):\n    os.makedirs(index_dir)\n\nschema = Schema(title=TEXT(stored=True), content=TEXT)\nix = create_in(index_dir, schema)\n```","cause":"The directory specified for creating or opening the Whoosh index does not exist, or the path is incorrect.","error":"OSError: [Errno 2] No such file or directory: 'path/to/index/_MAIN_0.toc'"},{"fix":"Ensure `QueryParser` is initialized with a schema and a default field, and always pass a non-empty, valid query string to its `parse()` method.\n\n```python\nfrom whoosh.qparser import QueryParser\nfrom whoosh.fields import Schema, TEXT\n\nmy_schema = Schema(title=TEXT(stored=True), content=TEXT(stored=True))\n# Initialize QueryParser with a default field and the schema\nqp = QueryParser(\"content\", schema=my_schema)\n\n# Ensure the query string is not empty or invalid\nquery_string = \"search term\"\nif query_string:\n    my_query = qp.parse(query_string)\n```","cause":"The `QueryParser` was instantiated without a schema or a default field, or an empty/invalid query string was passed to its `parse()` method.","error":"whoosh.query.qcore.QueryError: Not enough arguments for QueryParser"}],"ecosystem":"pypi","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":"2.7.4","cli_name":"whoosh","cli_version":"sh: 1: whoosh: not found","type":"library","homepage":"http://bitbucket.org/mchaput/whoosh","github":null,"docs":null,"changelog":null,"pypi":"https://pypi.org/project/whoosh/","npm":null,"openapi_spec":null,"status_page":null,"smithery":null,"categories":["database","data"],"base_url":null,"auth_type":null,"provenance":{"verified_status":"passing","verified_at":"2026-06-28","last_verified":"2026-08-29","next_check":"2026-07-28","install_tag":null}}