npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@magierin-schnee/solr-client

v1.1.0

Published

A simple and efficient Solr client for Node.js applications. Supports Solr 5 through 10+.

Readme

@magierin-schnee/solr-client

A powerful and flexible Node.js client for Apache Solr (versions 5 through 10+), offering an intuitive API for document management, advanced querying, and collection administration.


✨ Features

  • Solr 5–10+ Compatible: Works across all modern Solr versions, including Solr 10.
  • Custom Request Handlers: Query any handler (/suggest, /browse, custom handlers) directly via URL path — no reliance on the deprecated qt parameter.
  • Full-Featured Document API: Add, update, and delete documents with simple, chainable methods.
  • Powerful Query Builder: Construct sophisticated queries with a fluent API.
  • JSON Facet API: Full support for terms, range, query, and nested facets.
  • Streaming Support: Efficiently index large datasets via streams.
  • Collection Management: Administer SolrCloud collections with ease.
  • Robust Error Handling: Modern async/await and promise-based error handling.

🚀 Getting Started

1. Installation

npm install @magierin-schnee/solr-client

2. Creating a Client

import { createClient } from '@magierin-schnee/solr-client'

const client = createClient({
  host: '127.0.0.1',
  port: 8983,
  core: 'my_core',
  path: '/solr',
  secure: false,
  bigint: false,
})

3. Authentication

client.setBasicAuth('username', 'password')

// To remove authentication
client.clearAuth()

Core Functionality

Adding Documents

// Single document
await client.addDocuments({ id: '1', name: 'Example' }, { commit: true })

// Multiple documents
await client.addDocuments([
  { id: '2', name: 'Another' },
  { id: '3', name: 'Yet Another' },
], { commit: true })

Searching Documents

// Using the default /select handler
const query = client.createQuery().setQuery('name:Example')
const response = await client.searchDocuments(query)
console.log(response.response.docs)

// Get all documents
const all = await client.searchAllDocuments()

Custom Request Handlers

For Solr 7+ (and especially Solr 10), the qt parameter is ignored by default. Use searchByHandler() to query custom handlers directly via the URL path:

// Query a custom 'suggest' handler
const query = client.createQuery().setQuery('kia')
const result = await client.searchByHandler('suggest', query)

// Query a custom 'suggestedBrands' handler
const query = client.createQuery()
  .setQuery('*:*')
  .addFilter('brandSlug:toyota')
const result = await client.searchByHandler('suggestedBrands', query)

You can also use executeQuery() for full control:

const result = await client.executeQuery('myCustomHandler', query)

Retrieving Documents by ID

const response = await client.getDocumentsById('1')
const multi = await client.getDocumentsById(['1', '2', '3'])

Deleting Documents

await client.deleteById('1', { commit: true })
await client.deleteByField('name', 'Example', { commit: true })
await client.deleteByQuery('name:Example', { commit: true })
await client.deleteAllDocuments({ commit: true })

Committing Changes

await client.commit()
await client.softCommit()
await client.prepareCommit()

Querying

Build complex queries using the Query class:

const query = client
  .createQuery()
  .setQuery('*:*')
  .addFilter('age:25')
  .setOffset(0)
  .setLimit(10)
  .setSort({ score: 'desc' })

const response = await client.searchDocuments(query)

Key Query Methods

| Method | Description | Example | | ------------------------- | ----------------------------------------- | ---------------------------------------------------------------------- | | setQuery(query) | Sets the main query string. | .setQuery('name:Example') | | addFilter(filter) | Adds a filter query (fq). | .addFilter('category:books') | | addFilters(filters) | Adds multiple filter queries. | .addFilters(['inStock:true', 'price:[* TO 100]']) | | setOffset(offset) | Sets the starting offset for pagination. | .setOffset(10) | | setLimit(limit) | Limits the number of results. | .setLimit(20) | | setSort(fields) | Defines sort order. | .setSort({ score: 'desc' }) | | setResponseFields(fields) | Specifies fields to return. | .setResponseFields(['id', 'name']) | | setFacets(config) | Configures faceting (JSON Facet API). | .setFacets({ categories: { type: 'terms', field: 'cat', limit: 10 } }) | | setHighlighting(config) | Configures highlighting. | .setHighlighting({ on: true, fl: 'content' }) | | setParam(key, value) | Sets any arbitrary Solr parameter. | .setParam('defType', 'edismax') | | useExtendedDisMax() | Enables the eDisMax query parser. | .useExtendedDisMax() |


Advanced Facets

Full support for Solr's JSON Facet API:

Terms Facet

const query = client.createQuery()
  .setQuery('*:*')
  .setLimit(0)
  .setFacets({
    category: { type: 'terms', field: 'category', limit: 10, mincount: 1 },
  })

const response = await client.searchDocuments(query)
// response.facets.category.buckets → [{ val: 'electronics', count: 75 }, ...]

Range Facet

const query = client.createQuery()
  .setQuery('*:*')
  .setLimit(0)
  .setFacets({
    price: { type: 'range', field: 'price', start: 0, end: 1000, gap: 100 },
  })

Query Facet

const query = client.createQuery()
  .setQuery('*:*')
  .setLimit(0)
  .setFacets({
    inStock: { type: 'query', q: 'inStock:true' },
  })

Nested Facets

const query = client.createQuery()
  .setQuery('*:*')
  .setLimit(0)
  .setFacets({
    ratings: {
      type: 'query',
      q: '*:*',
      facet: {
        high: { type: 'query', q: 'rate:[9.0 TO *]' },
        good: { type: 'query', q: '+rate:[8.0 TO *] -rate:[9.0 TO *]' },
      },
    },
  })

Streaming Documents

const { stream, response } = client.createDocumentStream({ commit: true })

stream.write({ id: '1', name: 'Streamed Document' })
stream.end()

const result = await response

Managing Collections

const collection = client.createCollection()
const response = await client.manageCollection(collection)

Error Handling

import { SolrError } from '@magierin-schnee/solr-client'

try {
  await client.addDocuments(document)
} catch (error) {
  if (error instanceof SolrError) {
    console.error('HTTP Status:', error.httpStatusCode)
    console.error('Solr Code:', error.solrCode)
    console.error('Message:', error.message)
    console.error('Metadata:', error.metadata)
  }
}

Migration from 0.x

Breaking Changes in 1.0.0

  1. executeQuery() is now public — You can call client.executeQuery(handler, query) directly for full control over which handler receives the request.

  2. New searchByHandler() method — The recommended way to query custom request handlers:

    // Before (0.x): relied on qt parameter, broken in Solr 7+
    const query = client.createQuery().setRequestHandler('suggest').setQuery('kia')
    const result = await client.searchDocuments(query)
    
    // After (1.0): handler goes in the URL path, works on all Solr versions
    const query = client.createQuery().setQuery('kia')
    const result = await client.searchByHandler('suggest', query)
  3. setRequestHandler() is deprecated — It still works (sets qt param) but is ignored by Solr 7+ by default. Use searchByHandler() instead.

  4. setParam() is now public — Set any arbitrary Solr parameter directly on the query.

  5. escapeLuceneChars and convertDatesToISO are now exported from the main entry point.

Non-Breaking Changes

  • searchDocuments() still works exactly as before (always hits /select).
  • All existing Query builder methods are unchanged.
  • All document operations (add, delete, commit) are unchanged.
  • SolrError now includes solrCode for the Solr-specific error code.

Solr Version Compatibility

| Solr Version | Status | |---|---| | 5.x | ✅ Tested | | 6.x | ✅ Tested | | 7.x | ✅ Tested | | 8.x | ✅ Tested | | 9.x | ✅ Tested | | 10.x | ✅ Tested |


License

This project is licensed under the MIT License.