Hybrid Search

Opensolr Hybrid Search — find answers to your questions

Using NLP Models

Using NLP Models in Your Solr schema_extra_types.xml

Leverage the power of Natural Language Processing (NLP) right inside Solr!
With built-in support for OpenNLP models, you can add advanced tokenization, part-of-speech tagging, named entity recognition, and much more—no PhD required.


Why Use NLP Models in Solr?

Integrating NLP in your schema allows you to:

  • Extract nouns, verbs, or any part-of-speech you fancy.
  • Perform more relevant searches by filtering, stemming, and synonymizing.
  • Create blazing-fast autocomplete and suggestion features via EdgeNGrams.
  • Support multi-language, linguistically smart queries.

In short: your Solr becomes smarter and your users get better search results.


Example: Dutch Edge NGram Nouns Field

Here’s a typical fieldType in your schema_extra_types.xml using OpenNLP:

<fieldType name="text_edge_nouns_nl" class="solr.TextField" positionIncrementGap="100">
  <analyzer type="index">
    <tokenizer class="solr.OpenNLPTokenizerFactory" sentenceModel="/opt/nlp/nl-sent.bin" tokenizerModel="/opt/nlp/nl-token.bin"/>
    <filter class="solr.OpenNLPPOSFilterFactory" posTaggerModel="/opt/nlp/nl-pos-maxent.bin"/>
    <filter class="solr.TypeTokenFilterFactory" types="pos_edge_nouns_nl.txt" useWhitelist="true"/>
    <filter class="solr.LowerCaseFilterFactory"/>
    <filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
    <filter class="solr.EdgeNGramFilterFactory" minGramSize="2" maxGramSize="25"/>
  </analyzer>
  <analyzer type="query">
    <tokenizer class="solr.OpenNLPTokenizerFactory" sentenceModel="/opt/nlp/nl-sent.bin" tokenizerModel="/opt/nlp/nl-token.bin"/>
    <filter class="solr.OpenNLPPOSFilterFactory" posTaggerModel="/opt/nlp/nl-pos-maxent.bin"/>
    <filter class="solr.TypeTokenFilterFactory" types="pos_edge_nouns_nl.txt" useWhitelist="true"/>
    <filter class="solr.LowerCaseFilterFactory"/>
    <filter class="solr.SynonymGraphFilterFactory" synonyms="synonyms_edge_nouns_nl.txt"/>
    <filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
  </analyzer>
</fieldType>

Important Details

  • Model Paths:
    Always reference the full absolute path for NLP model files. For example:

    sentenceModel="/opt/nlp/nl-sent.bin"
    tokenizerModel="/opt/nlp/nl-token.bin"
    posTaggerModel="/opt/nlp/nl-pos-maxent.bin"
    

    This ensures Solr always finds your precious language models—no “file not found” drama!

  • Type Token Filtering:
    The TypeTokenFilterFactory with useWhitelist="true" will only keep tokens matching the allowed parts of speech (like nouns, verbs, etc.), as defined in pos_edge_nouns_nl.txt. This keeps your index tight and focused.

  • Synonym Graphs:
    Add SynonymGraphFilterFactory to enable query-side expansion. This is great for handling multiple word forms, synonyms, and local lingo.


‍Best Practices & Gotchas

  • Keep your NLP model files up to date and tested for your language version!
  • If using multiple languages, make sure you have the right models for each language. (No, Dutch models won’t help with Klingon. Yet.)
  • EdgeNGram and NGram fields are fantastic for autocomplete—but don’t overdo it, as they can bloat your index if not tuned.
  • Use RemoveDuplicatesTokenFilterFactory to keep things clean and efficient.

Not Just for Dutch!

You can set up similar analyzers for English, undefined language, or anything you like. For example:

<fieldType name="text_nouns_en" class="solr.TextField" positionIncrementGap="100">
  <analyzer type="index">
    <tokenizer class="solr.OpenNLPTokenizerFactory" sentenceModel="/opt/nlp/en-sent.bin" tokenizerModel="/opt/nlp/en-token.bin"/>
    <filter class="solr.OpenNLPPOSFilterFactory" posTaggerModel="/opt/nlp/en-pos-maxent.bin"/>
    <filter class="solr.TypeTokenFilterFactory" types="pos_nouns_en.txt" useWhitelist="true"/>
    <filter class="solr.LowerCaseFilterFactory"/>
    <filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
  </analyzer>
  <analyzer type="query">
    <tokenizer class="solr.OpenNLPTokenizerFactory" sentenceModel="/opt/nlp/en-sent.bin" tokenizerModel="/opt/nlp/en-token.bin"/>
    <filter class="solr.OpenNLPPOSFilterFactory" posTaggerModel="/opt/nlp/en-pos-maxent.bin"/>
    <filter class="solr.TypeTokenFilterFactory" types="pos_nouns_en.txt" useWhitelist="true"/>
    <filter class="solr.LowerCaseFilterFactory"/>
    <filter class="solr.SynonymGraphFilterFactory" synonyms="synonyms_nouns_en.txt"/>
    <filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
  </analyzer>
</fieldType>

Keep It Organized

  • Store all model files in a single, logical directory (like /opt/nlp/), and keep a README so you know what’s what.
  • Protect those models! They’re your “brains” for language tasks.

Wrap-up

Using NLP models in your Solr analyzers will supercharge your search, make autocomplete smarter, and help users find what they’re actually looking for (even if they type like my cat walks on a keyboard).

Need more examples?
Check out the Solr Reference Guide - OpenNLP Integration or the OpenNLP NER guide for Opensolr.


Happy indexing, and may your tokens always be well-typed!

Read Full Answer

How to use OpenNLP (NER) with Opensolr

OpenNLP + Opensolr Integration Guide

Heads up!
Before you dive into using NLP models with your Opensolr index, please contact us to request the NLP models to be installed for your Opensolr index.
We'll reply with the correct path to use for the .bin files in your schema.xml or solrconfig.xml.


What’s this all about?

This is your step-by-step guide to using OpenNLP models with Opensolr. In this walkthrough, we’ll cover Named Entity Recognition (NER) using default OpenNLP models, so you can start extracting valuable information (like people, places, and organizations) directly from your indexed data.

Note:
Currently, these models are enabled by default only in the Germany, Solr Version 9 environment. So, if you want an easy life, create your index there!
We’re happy to set up the models in any region (or even your dedicated Opensolr infrastructure for corporate accounts) if you reach out via our contact form.

Add New Opensolr Index

The default OpenNLP models are on the official OpenNLP website.


Step-by-Step: Enable NLP Entity Extraction

  1. Create your Opensolr Index

    • Use this guide to create your Opensolr index (Solr 7, 8 or 9; Solr versions below 8 are retired on 01/01/2027).
    • Pro Tip: Creating your index in the Germany Solr 9 Web Crawler Environment skips most of the manual steps below.
  2. Edit Your schema.xml

    • Go to the Opensolr Control Panel.
    • Click your Index Name → Configuration tab → select schema.xml to edit.
    Edit schema.xml
    • Add these snippets:

      Dynamic Field (for storing entities):

<dynamicField name="*_s" type="string" multiValued="true" indexed="true" stored="true" termVectors="true" termPositions="true" termOffsets="true" storeOffsetsWithPositions="true" />
  **NLP Tokenizer fieldType:**
<fieldType name="text_nlp" class="solr.TextField" positionIncrementGap="100">
    <analyzer>
        <charFilter class="solr.MappingCharFilterFactory" mapping="mapping-ISOLatin1Accent.txt"/>
        <tokenizer class="solr.OpenNLPTokenizerFactory"
            sentenceModel="en-sent.bin"
            tokenizerModel="en-token.bin"/>
         <filter class="solr.OpenNLPPOSFilterFactory" posTaggerModel="en-pos-maxent.bin"/>
         <filter class="solr.OpenNLPChunkerFilterFactory" chunkerModel="en-chunker.bin"/>
         <filter class="solr.TypeAsPayloadFilterFactory"/>
     </analyzer>
 </fieldType>
- **Important:** Don’t use the `text_nlp` type for your dynamic fields! It’s only for the update processor.
  1. Save, then Edit Your solrconfig.xml

    Save schema.xml
    • Add the following updateRequestProcessorChain (and corresponding requestHandler):
<requestHandler name="/update" class="solr.UpdateRequestHandler" >
    <lst name="defaults">
        <str name="update.chain">nlp</str>
    </lst>
</requestHandler>
<updateRequestProcessorChain name="nlp">
    <!-- Extract English People Names -->
    <processor class="solr.OpenNLPExtractNamedEntitiesUpdateProcessorFactory">
        <str name="modelFile">en-ner-person.bin</str>
        <str name="analyzerFieldType">text_nlp</str>
        <arr name="source">
            <str>title</str>
            <str>description</str>
        </arr>
        <str name="dest">people_s</str>
    </processor>
    <!-- Extract Spanish People Names -->
    <processor class="solr.OpenNLPExtractNamedEntitiesUpdateProcessorFactory">
        <str name="modelFile">es-ner-person.bin</str>
        <str name="analyzerFieldType">text_nlp</str>
        <arr name="source">
            <str>title</str>
            <str>description</str>
        </arr>
        <str name="dest">people_s</str>
    </processor>
    <!-- Extract Locations -->
    <processor class="solr.OpenNLPExtractNamedEntitiesUpdateProcessorFactory">
        <str name="modelFile">en-ner-location.bin</str>
        <str name="analyzerFieldType">text_nlp</str>
        <arr name="source">
            <str>title</str>
            <str>description</str>
        </arr>
        <str name="dest">location_s</str>
    </processor>
    <!-- Extract Organizations -->
    <processor class="solr.OpenNLPExtractNamedEntitiesUpdateProcessorFactory">
        <str name="modelFile">en-ner-organization.bin</str>
        <str name="analyzerFieldType">text_nlp</str>
        <arr name="source">
            <str>title</str>
            <str>description</str>
        </arr>
        <str name="dest">organization_s</str>
    </processor>
    <!-- Language Detection -->
    <processor class="org.apache.solr.update.processor.OpenNLPLangDetectUpdateProcessorFactory">
        <str name="langid.fl">title,text,description</str>
        <str name="langid.langField">language_s</str>
        <str name="langid.model">langdetect-183.bin</str>
    </processor>
    <!-- Remove duplicate extracted entities -->
    <processor class="solr.UniqFieldsUpdateProcessorFactory">
        <str name="fieldRegex">.*_s</str>
    </processor>
    <processor class="solr.RunUpdateProcessorFactory" />
</updateRequestProcessorChain>
  1. Populate Test Data (for the impatient!)

    • If you’re using the Germany Solr 9 Web Crawler, you can crawl your site and extract all the juicy entities automatically.
    • Or, insert a sample doc via Solr Admin:
    Solr Admin Panel Add Docs to Solr Index

    Sample JSON:

{
    "id": "1",
    "title": "Jack Sparrow was a pirate. Many feared him. He used to live in downtown Las Vegas.",
    "description": "Jack Sparrow and Janette Sparrowa, are now on their way to Monte Carlo for the summer vacation, after working hard for Microsoft, creating the new and exciting Windows 11 which everyone now loves. :)",
    "text": "The Apache OpenNLP project is developed by volunteers and is always looking for new contributors to work on all parts of the project. Every contribution is welcome and needed to make it better. A contribution can be anything from a small documentation typo fix to a new component.Learn more about how you can get involved."
}
  1. See the Magic!

    • Visit the query tab to see extracted entities in action!
    Solr Query Opensolr NLP End Result

Related: Using NLP Models, a worked OpenNLP fieldType for part of speech tagging and autocomplete.

Read Full Answer

Hybrid Search Live Demo — Try It Yourself

Did you know? You can now use the {!hybrid} parser — a custom Opensolr Solr query parser that gives you better hybrid search: correct keyword + vector fusion, real search modes, and natural-language, cross-lingual queries out of the box. Learn more →
Live Search Demo

Hybrid Search in Action

Keyword matching + semantic understanding, working together. Click any query below to run it live — no sign-up needed.

How It Works

Your Query"find me X"Keyword MatchBM25 · edismax · boostSemantic Matchmultilingual E5 · 1024-dim KNN{!hybrid} Parserprivate to OpensolrHybrid Scoreweighted blendBest Resultsranked by relevance

Keyword Layer
Finds docs with matching terms — fast, precise, field-weighted
Semantic Layer
Finds docs by meaning — works even with zero lexical overlap
Score Fusion
Our own private {!hybrid} parser blends keyword and meaning scores per document, tuned with one alpha knob and four modes
Zero Config
Automatic on all vector-enabled indexes — no query changes needed

Four Indexes, Four Domains

Each index below is a real, live Opensolr instance. Every query was chosen to demonstrate semantic understanding — words in the query often do not appear in the top-ranked documents.

Ready to add hybrid search to your index?

One flip. Instant semantic search.

Create your index in a vector region, or install the Opensolr vector schema on one with apply_schema, and hybrid search activates automatically. No query changes: the documents you send are embedded for you.

Read Full Answer