Solr Functions
Overview
Martini's Solr Functions let you manage Solr cores and index, delete, query, facet, and generate statistics against documents in a search index directly from your workflows and services. They give you programmatic control over a Solr core as an alternative — or a complement — to configuring it declaratively through Martini package configuration.
What You Will Learn
- How to add and remove Solr cores from a Martini package with
addCoreandremoveCore - How to index and partially update documents with
writeDataModelToIndex, and commit pending changes withcommit - How to delete documents with
deleteById,deleteByQuery, anddeleteAll - How to query a core with
queryandsearchCore, and shape requests withsolrParams - How to run faceted searches and generate field statistics
- How to stream large volumes of documents into a core with
openDocumentOutputCursor - How the shared
coreNameandpackageNameparameters identify which Solr core a function targets
When To Use This
Use Solr Functions when you need runtime, code-level control over a Solr search index instead of, or alongside, the Solr Search API. Typical scenarios include:
- Indexing or updating documents as part of a data synchronization workflow or service
- Deleting stale documents by ID or by query when source records are removed or replaced
- Building a custom search or faceted-navigation experience backed by a Solr core
- Generating field statistics or facet breakdowns for reporting or analytics
- Streaming a large batch of documents into a core without accumulating them all in memory
- Adding, removing, or reloading a core as part of a package's deployment or configuration lifecycle
Prerequisites
- Martini Designer installed and running
- A Martini package with a service or workflow to invoke the functions from
- A Solr core configured for the package — see Martini Creating a Core on Solr
- Basic understanding of the following:
- Invoke Function Node for workflows
- Function Step for services
Solr Functions Reference
Solr Functions, grouped under the Solr folder in the Functions view, cover core management, document indexing and deletion, querying, faceted search, field statistics, and streaming document writes.
Understanding the coreName and packageName Parameters
Every Solr Function accepts a coreName parameter identifying the Solr core to act on, and most also accept a
packageName parameter identifying which Martini package's package.xml declares that core.
| Parameter | Required | Description |
|---|---|---|
coreName |
Yes | The name of the Solr core to target. searchCore treats a blank coreName as querying across all records instead. |
packageName |
No | The name of the package where the Solr core resides. Leave it blank to target a core declared in the current package. |
Managing Solr Cores
addCore, removeCore, and reloadCore let you manage a Solr core's lifecycle within a package without editing
package.xml by hand.
Adding and Removing Cores with addCore and removeCore
addCore(coreName, packageName) adds the configured Solr core to the specified package. removeCore(coreName, packageName) removes an existing Solr core from a package.
| Function | Parameter | Required | Description |
|---|---|---|---|
addCore(coreName, packageName) |
coreName |
Yes | The name of the Solr core to add. |
packageName |
No | The package to add the core to. Leave blank to use the package where the service is invoked. | |
removeCore(coreName, packageName) |
coreName |
Yes | The name of the existing Solr core to remove. |
packageName |
No | The package the core belongs to. Leave blank to use the package where the service is invoked. |
1 2 | |
addCore throws IOException if the core cannot be added.
Reloading a Core with reloadCore
reloadCore(coreName, packageName) reloads the specified Solr core, applying any configuration changes made
since it was last loaded, without requiring a restart of Martini.
1 | |
reloadCore throws SolrServerException or IOException if the reload fails.
Migrating from Deprecated Core Management Overloads
Martini Runtime v3.0.0 replaced the following overloads. The new overloads no longer support embedded ("local") Solr, so they drop the parameters that only applied to that mode:
| Deprecated overload | Replacement | Notes |
|---|---|---|
addCore(coreName, modelNamespace, uniqueKey, packageName) |
addCore(coreName, packageName) |
No longer generates a Solr schema from a data model's modelNamespace, and no longer accepts a uniqueKey. |
removeCore(coreName, packageName, removeFiles) |
removeCore(coreName, packageName) |
No longer supports the removeFiles flag for deleting the core's configuration files. |
Update calls using the deprecated parameters
If your workflows or services call addCore with a modelNamespace or uniqueKey, or removeCore with
removeFiles, update them to the new overloads before upgrading to a Solr setup without embedded Solr
support, since those parameters no longer have any effect on the new overloads.
Indexing and Updating Documents
writeDataModelToIndex indexes a document or partially updates an existing one, and commit makes pending
changes visible to queries.
Indexing a Document with writeDataModelToIndex
writeDataModelToIndex(coreName, packageName, dataModel) adds a new document or updates an existing one,
depending on the provided dataModel. Solr relies on the core's configured schema to identify which properties
of the model to index.
| Parameter | Required | Description |
|---|---|---|
coreName |
Yes | The name of the Solr core where the document will belong. |
packageName |
No | The package where the Solr core resides. Leave blank to use the package where the workflow or service is invoked. |
dataModel |
Yes | The data model to index. |
1 | |
When updating an existing document, updates are partial — only the properties present on dataModel are
indexed, leaving the document's other fields unchanged. dataModel can also use FieldModifier properties,
which mirror the modifier argument of a Solr SolrInputDocument, letting you control how each field is applied
during the update. See Updating parts of documents
for the underlying Solr behavior.
writeDataModelToIndex returns an updateResponse and throws SolrServerException or IOException if the
index operation fails.
Committing Pending Changes with commit
commit(coreName, packageName) explicitly commits all pending documents to the specified Solr core. Use it
after direct index operations to make documents visible to queries without relying on a cursor's automatic
commit mode.
1 | |
commit returns void and throws IOException or SolrServerException if the commit fails.
Deleting Documents
deleteById, deleteByQuery, and deleteAll remove documents from a Solr core.
| Function | Parameter | Required | Description |
|---|---|---|---|
deleteById(coreName, packageName, ids) |
ids |
Yes | The IDs of all Solr documents to delete. |
deleteByQuery(coreName, packageName, query) |
query |
Yes | A query selecting which Solr documents to delete. |
deleteAll(coreName, packageName, commit) |
commit |
No | Whether to immediately commit the deletion. Defaults to true. |
1 2 3 | |
deleteAll issues a delete-by-query using the wildcard query *:* to clear every document from the core. When
commit is true, the deletion is committed immediately so the index is empty and queryable right away; when
false, the deletion is buffered until the next commit. All three functions return an updateResponse and throw
SolrServerException or IOException if the delete operation fails.
Querying and Searching Documents
query and searchCore both retrieve documents from a Solr core, but they differ in how much control they
give you over the request.
Understanding the solrParams Input
query and every faceted search and field statistics function accept a solrParams parameter — a list of
entries, each defining a single Solr request parameter as a paramKey/paramValue pair. Use it to pass any
parameter Solr's request handlers accept, such as q, sort, rows, start, facet.field, or facet.pivot.
1 2 3 4 | |
Querying a Core with query
query(coreName, packageName, solrParams) sends solrParams to the core as-is and returns the raw response
from the Solr server.
| Parameter | Required | Description |
|---|---|---|
coreName |
Yes | The name of the Solr core which will receive the query. |
packageName |
No | The package where the Solr core resides. Leave blank to use the package where the service is invoked. |
solrParams |
No | The Solr query parameters, as paramKey/paramValue pairs. |
query returns a queryResponse and does not paginate or shape the response for you — use it when you need
full control over the request sent to Solr.
Searching a Core with searchCore
searchCore wraps common search options — query, sorting, field selection, and pagination — into discrete
parameters instead of raw solrParams entries.
| Parameter | Required | Description |
|---|---|---|
query |
No | The search query. Defaults to *:*. |
coreName |
Yes | The name of the Solr core which will receive the query. Leave blank to query across all records. |
packageName |
No | The package where the Solr core resides. Leave blank to use the package where the service is invoked. |
sortField |
No | The field to sort results by. |
sortType |
No | The sort order — Ascending or Descending. Defaults to Ascending. |
fields |
No | The fields to include in the response. Leave blank to include all fields. |
pageSize |
No | The number of results per page. Defaults to 10. |
page |
No | The page of results to display. Defaults to 1. |
1 2 3 4 5 6 7 8 9 | |
searchCore returns a queryResponse — use it instead of query when you want built-in pagination and sorting
without assembling solrParams entries yourself.
Running Faceted Searches
Faceted search functions return the unique values found for one or more fields, along with the number of
documents where each value occurs. All faceted search functions accept solrParams in addition to the
parameters listed below. See Faceting for background
on Solr's faceting behavior.
| Function | Output Property (Type) | Description |
|---|---|---|
fieldValueFacetSearch(coreName, packageName, fieldName, solrParams) |
fieldValueFacet (Facet) |
Returns the unique values found for fieldName and the document count for each value. |
multiFieldValueFacetSearch(coreName, packageName, solrParams) |
fieldValueFacet (Facet[]) |
Same as fieldValueFacetSearch, but for every field specified with facet.field entries in solrParams. |
rangeFacetSearch(coreName, packageName, fieldName, solrParams) |
rangeFacet (FacetRange) |
Returns the values found for fieldName within a range, and the document count for each value. |
pivotFacetSearch(coreName, packageName, fieldName, solrParams) |
pivotFacet (PivotField) |
Returns the values found for fieldName as a pivot facet, and the document count for each value. |
multiPivotFacetSearch(coreName, packageName, solrParams) |
pivotFacet (PivotField[]) |
Same as pivotFacetSearch, but for every pivot combination specified with facet.pivot entries in solrParams. |
fieldName is required for fieldValueFacetSearch, rangeFacetSearch, and pivotFacetSearch.
multiFieldValueFacetSearch requires solrParams to include at least one facet.field entry, and
multiPivotFacetSearch requires at least one facet.pivot entry, since neither function accepts a single
fieldName parameter.
1 2 3 4 5 6 | |
Generating Field Statistics
fieldStatisticsSearch and multiFieldStatisticsSearch generate statistics — such as minimum, maximum, and
sum — for one or more fields in a core.
| Function | Output Property (Type) | Description |
|---|---|---|
fieldStatisticsSearch(coreName, packageName, fieldName, solrParams) |
stats (FieldStatsInfo) |
Generates statistics for fieldName. |
multiFieldStatisticsSearch(coreName, packageName, solrParams) |
stats (FieldStatsInfo[]) |
Generates statistics for one or more fields. |
fieldName is required for fieldStatisticsSearch. Both statistics functions generate statistics for one or more fields in a core.
1 | |
Streaming Document Writes with openDocumentOutputCursor
openDocumentOutputCursor opens an output cursor for indexing a
large number of documents without accumulating them all in memory. Use it instead of repeated
writeDataModelToIndex calls when writing a large volume of documents. Map the returned cursor to the output
array of a Repeat Node in a workflow, or an
Iterate Step in a service; Martini closes the cursor automatically at the
end of the execution.
| Parameter | Required | Description |
|---|---|---|
coreName |
Yes | The name of the Solr core where the documents will belong. |
packageName |
No | The package where the Solr core resides. Leave blank to use the package where the workflow or service is invoked. |
commitMode |
No | When the cursor commits its cached documents to Solr. Defaults to On Close. |
closeClient |
No | Whether to close the client after the cursor has been exhausted. Defaults to false. |
batchSize |
No | How many written models to cache before sending them to Solr. Defaults to 1000. |
commitMode accepts one of the following values:
| Value | Behavior |
|---|---|
Never |
Do not commit any documents to Solr. |
Batch |
Commit the cached documents only when batchSize is satisfied. |
On Close |
Commit documents only when the cursor is closed. This is the default. |
1 2 3 4 5 6 | |
flowchart LR
s[...]
a["`**Function Node:** Open document output cursor and map to _myCursor_`"]
b["`**Repeat Node:** Iterate over _movies_ with _myCursor_ as the output array`"]
c["`**Map Step**: Map the current _movies_ entry to the current _myCursor_ entry`"]
d[...]
s --> a --> b -- each --> c
b -- then --> d
Map the returned cursor to a data model array. For each iteration, map the source data to the current cursor
entry; Martini accumulates the entries and sends them to Solr once batchSize is reached (in Batch mode) or
when the cursor closes, according to commitMode. If you set commitMode to Never, call
commit afterward to make the indexed documents visible to queries.
Solr Functions Benefits and Use Cases
Solr Functions let you drive a Solr-backed search index entirely from workflow and service logic, without maintaining separate indexing scripts or relying solely on the Solr Search API. Common scenarios include:
- Data synchronization — Keep a Solr core in sync with a source system by indexing changed records with
writeDataModelToIndexand removing deleted records withdeleteByIdordeleteByQuery. - Bulk reindexing — Use
openDocumentOutputCursorto reindex an entire dataset without accumulating every document in memory at once. - Custom search experiences — Build search endpoints backed by
queryorsearchCore, combined with faceted search functions for filter navigation. - Analytics and reporting — Use
fieldStatisticsSearchandmultiFieldStatisticsSearchto generate aggregate statistics for dashboards, without a separate analytics pipeline. - Package lifecycle management — Add, remove, or reload cores with
addCore,removeCore, andreloadCoreas part of a package's setup or teardown logic.
Troubleshooting Solr Function Issues
| Problem | Detection | Cause | Fix |
|---|---|---|---|
Function throws SolrServerException or IOException |
Call fails immediately with an exception | coreName does not match a core configured for packageName, or the Solr server is unreachable |
Verify the core is registered in package.xml for packageName and that the Solr server is running and reachable |
writeDataModelToIndex overwrites fields you expected to keep |
Document fields are unexpectedly cleared after indexing | dataModel was populated with default or null values for fields not intended to change |
Populate only the fields you intend to update, or use FieldModifier properties for explicit partial updates |
Indexed documents are not returned by query or searchCore |
Newly indexed documents are missing from search results | Changes were written with commitMode set to Never, or a direct index call was never committed |
Call commit after indexing, or use a commitMode of Batch or On Close with openDocumentOutputCursor |
multiFieldValueFacetSearch or multiPivotFacetSearch returns no facets |
Empty facet results despite indexed data | solrParams did not include the required facet.field or facet.pivot entries |
Add at least one facet.field (for multiFieldValueFacetSearch) or facet.pivot (for multiPivotFacetSearch) entry to solrParams |
addCore or removeCore call has no effect |
Core is not added, removed, or behaves unexpectedly | The deprecated overload's modelNamespace, uniqueKey, or removeFiles parameters are being used against a setup without embedded Solr support |
Migrate to the current addCore(coreName, packageName) or removeCore(coreName, packageName) overload — see Migrating from Deprecated Core Management Overloads |
Helpful Resources
- Martini Creating a Core on Solr — Configure and register a Solr core for a Martini package
- Martini Searching Solr Documents — Additional search examples using Solr Functions,
SolrClient, and the Solr Search API - Martini Cursors — Deep dive into how cursors work and how to manage them efficiently
- Invoke Function Node — Call Solr Functions from within a workflow
- Function Step — Call Solr Functions from within a service
SolrMethodsclass Javadoc — Full class-level reference- Community Q&A: Martini Community
Have a question? Post or search it here.