Skip to main content

A Solr client library written in Rust

Project description

Solrstice: A Solr 8+ Client for Rust and Python

Solrstice is a solr client library written in rust. With this wrapper you can use it in python.

Both asyncio and blocking clients are provided. All apis have type hints.

Features

  • Config API
  • Collection API
  • Alias API
  • Select Documents
    • Grouping Component Query
    • DefTypes (lucene, dismax, edismax)
    • Facet Counts (Query, Field, Pivot)
    • Json Facet (Query, Stat, Terms, Nested)
  • Indexing Documents
  • Deleting Documents

Installation

pip install solrstice

Basic Usage

Async

import asyncio

from solrstice import SolrBasicAuth, SolrServerContext, SolrSingleServerHost, AsyncSolrCloudClient, UpdateQuery, \
    SelectQuery, DeleteQuery

# A SolrServerContext specifies how the library should interact with Solr
context = SolrServerContext(SolrSingleServerHost('localhost:8983'), SolrBasicAuth('solr', 'SolrRocks'))
client = AsyncSolrCloudClient(context)


async def main():
    # Create config and collection
    await client.upload_config('example_config', 'path/to/config')
    await client.create_collection('example_collection', 'example_config', shards=1, replication_factor=1)

    # Index a document
    await client.index(UpdateQuery(), 'example_collection', [{'id': 'example_document', 'title': 'Example document'}])

    # Search for the document
    response = await client.select(SelectQuery(fq=['title:Example document']), 'example_collection')
    docs = response.get_docs_response().get_docs()

    # Delete the document
    await client.delete(DeleteQuery(ids=['example_document']), 'example_collection')


asyncio.run(main())

Blocking

from solrstice import SolrBasicAuth, BlockingSolrCloudClient, SolrServerContext, SolrSingleServerHost, DeleteQuery, \
    SelectQuery, UpdateQuery

# A SolrServerContext specifies how the library should interact with Solr
context = SolrServerContext(SolrSingleServerHost('localhost:8983'), SolrBasicAuth('solr', 'SolrRocks'))
client = BlockingSolrCloudClient(context)

# Create config and collection
client.upload_config('example_config', 'path/to/config')
client.create_collection('example_collection', 'example_config', shards=1, replication_factor=1)

# Index a document
client.index(UpdateQuery(), 'example_collection', [{'id': 'example_document', 'title': 'Example document'}])

# Search for the document
response = client.select(SelectQuery(fq=['title:Example document']), 'example_collection')
docs = response.get_docs_response().get_docs()

# Delete the document
client.delete(DeleteQuery(ids=['example_document']), 'example_collection')

Grouping component

Field grouping

from solrstice import GroupingComponent, SelectQuery, SolrServerContext, AsyncSolrCloudClient
client = AsyncSolrCloudClient(SolrServerContext('localhost:8983'))

async def main():
  group_builder = GroupingComponent(fields=["age"], limit=10)
  select_builder = SelectQuery(fq=["age:[* TO *]"], grouping=group_builder)
  groups = (await client.select(select_builder, "example_collection")).get_groups()
  age_group = groups["age"]
  docs = age_group.get_field_result()

Query grouping

from solrstice import GroupingComponent, SelectQuery, SolrServerContext, AsyncSolrCloudClient
client = AsyncSolrCloudClient(SolrServerContext('localhost:8983'))

async def main():
  group_builder = GroupingComponent(queries=["age:[0 TO 59]", "age:[60 TO *]"], limit=10)
  select_builder = SelectQuery(fq=["age:[* TO *]"], grouping=group_builder)
  groups = (await client.select(select_builder, "example_collection")).get_groups()
  age_group = groups["age:[0 TO 59]"]
  group = age_group.get_query_result()
  docs = group.get_docs()

Query parsers

Lucene

from solrstice import LuceneQuery, SelectQuery, SolrServerContext, AsyncSolrCloudClient
client = AsyncSolrCloudClient(SolrServerContext('localhost:8983'))

async def main():
  query_parser = LuceneQuery(df="population")
  select_builder = SelectQuery(q="outdoors", def_type=query_parser)
  response = (await client.select(select_builder, "example_collection")).get_docs_response()
  assert response is not None
  docs = response.get_docs()

Dismax

from solrstice import DismaxQuery, SelectQuery, SolrServerContext, AsyncSolrCloudClient
client = AsyncSolrCloudClient(SolrServerContext('localhost:8983'))

async def main():
  query_parser = DismaxQuery(qf="interests^20", bq=["interests:cars^20"])
  select_builder = SelectQuery(q="outdoors", def_type=query_parser)
  response = (await client.select(select_builder, "example_collection")).get_docs_response()
  assert response is not None
  docs = response.get_docs()

Edismax

from solrstice import EdismaxQuery, SelectQuery, SolrServerContext, AsyncSolrCloudClient
client = AsyncSolrCloudClient(SolrServerContext('localhost:8983'))

async def main():
  query_parser = EdismaxQuery(qf="interests^20", bq=["interests:cars^20"])
  select_builder = SelectQuery(q="outdoors", def_type=query_parser)
  response = (await client.select(select_builder, "example_collection")).get_docs_response()
  assert response is not None
  docs = response.get_docs()

FacetSet Component

Pivot facet

from solrstice import FacetSetComponent, PivotFacetComponent, SelectQuery, SolrServerContext, AsyncSolrCloudClient
client = AsyncSolrCloudClient(SolrServerContext('localhost:8983'))

async def main():
  select_builder = SelectQuery(facet_set=FacetSetComponent(pivots=PivotFacetComponent(["interests,age"])))
  response = await client.select(select_builder, "example_collection")
  facets = response.get_facet_set()
  pivots = facets.get_pivots()
  interests_age = pivots.get("interests,age")

Field facet

from solrstice import FacetSetComponent, FieldFacetComponent, FieldFacetEntry, SelectQuery, SolrServerContext, AsyncSolrCloudClient
client = AsyncSolrCloudClient(SolrServerContext('localhost:8983'))

async def main():
  facet_set = FacetSetComponent(fields=FieldFacetComponent(fields=[FieldFacetEntry("age")]))
  select_builder = SelectQuery(facet_set=facet_set)
  response = await client.select(select_builder, "example_collection")
  facets = response.get_facet_set()
  fields = facets.get_fields()
  age = fields.get("age")

Query facet

from solrstice import AsyncSolrCloudClient, SolrServerContext, SelectQuery, FacetSetComponent, FacetSetComponent
client = AsyncSolrCloudClient(SolrServerContext('localhost:8983'))

async def main():
  select_builder = SelectQuery(facet_set=FacetSetComponent(queries=["age:[0 TO 59]"]))
  response = await client.select(select_builder, "example_collection")
  facets = response.get_facet_set()
  queries = facets.get_queries()
  query = queries.get("age:[0 TO 59]")

Json Facet Component

Query

from solrstice import JsonFacetComponent, JsonQueryFacet, SelectQuery, SolrServerContext, AsyncSolrCloudClient
async def main():
  client = AsyncSolrCloudClient(SolrServerContext('localhost:8983'))
  select_builder = SelectQuery(
      json_facet=JsonFacetComponent(
          facets={"below_60": JsonQueryFacet("age:[0 TO 59]")}
      )
  )
  response = await client.select(select_builder, "example_collection")
  facets = response.get_json_facets()
  below_60 = facets.get_nested_facets().get("below_60")
  assert below_60.get_count() == 4

Stat

from solrstice import JsonFacetComponent, JsonStatFacet, SelectQuery, SolrServerContext, AsyncSolrCloudClient
client = AsyncSolrCloudClient(SolrServerContext('localhost:8983'))

async def main():
  select_builder = SelectQuery(
      json_facet=JsonFacetComponent(
          facets={"total_people": JsonStatFacet("sum(count)")}
      )
  )
  response = await client.select(select_builder, "example_collection")
  facets = response.get_json_facets()
  total_people = facets.get_flat_facets().get("total_people")
  assert total_people == 1000

Terms

from solrstice import AsyncSolrCloudClient, SolrServerContext, SelectQuery, JsonFacetComponent, JsonTermsFacet
client = AsyncSolrCloudClient(SolrServerContext('localhost:8983'))

async def main():
  select_builder = SelectQuery(
      json_facet=JsonFacetComponent(facets={"age": JsonTermsFacet("age")})
  )
  response = await client.select(select_builder, "example_collection")
  facets = response.get_json_facets()
  age_buckets = facets.get_nested_facets().get("age").get_buckets()
  assert len(age_buckets) == 3

Nested

from solrstice import AsyncSolrCloudClient, SolrServerContext, SelectQuery, JsonFacetComponent, JsonQueryFacet, JsonStatFacet
client = AsyncSolrCloudClient(SolrServerContext('localhost:8983'))

async def main():
  select_builder = SelectQuery(
      json_facet=JsonFacetComponent(
          facets={
              "below_60": JsonQueryFacet(
                  "age:[0 TO 59]",
                  facets={"total_people": JsonStatFacet("sum(count)")},
              )
          }
      )
  )
  response = await client.select(select_builder, "example_collection")
  facets = response.get_json_facets()
  total_people = (
      facets.get_nested_facets()
      .get("below_60")
      .get_flat_facets()
      .get("total_people")
  )
  assert total_people == 750.0

Hosts

Single Server

from solrstice import SolrServerContext, SolrSingleServerHost, SolrBasicAuth, AsyncSolrCloudClient

context = SolrServerContext(SolrSingleServerHost('localhost:8983'), SolrBasicAuth('solr', 'SolrRocks'))
client = AsyncSolrCloudClient(context)

Multiple servers

from solrstice import SolrServerContext, SolrMultipleServerHost, SolrBasicAuth, AsyncSolrCloudClient

# The client will randomly select a server to send requests to. It will wait 5 seconds for a response, before trying another server.
context = SolrServerContext(
    SolrMultipleServerHost(["localhost:8983", "localhost:8984"], 5),
    SolrBasicAuth('solr', 'SolrRocks'),
)
client = AsyncSolrCloudClient(context)

Zookeeper

from solrstice import SolrServerContext, ZookeeperEnsembleHostConnector, SolrBasicAuth, AsyncSolrCloudClient

async def main():
  context = SolrServerContext(
      await ZookeeperEnsembleHostConnector(["localhost:2181"], 30).connect(),
      SolrBasicAuth('solr', 'SolrRocks'),
  )
  client = AsyncSolrCloudClient(context)

Notes

  • Multiprocessing does not work, and will block forever. Normal multithreading works fine.

  • Pyo3, the Rust library for creating bindings does not allow overriding the __init__ method on objects from Rust. __new__ has to be overridden instead.

    For example, if you want to create a simpler way to create a client

      from typing import Optional
      from solrstice import SolrServerContext, SolrSingleServerHost, SolrBasicAuth, AsyncSolrCloudClient, SolrAuth
      class SolrClient(AsyncSolrCloudClient):
          def __new__(cls, host: str, auth: Optional[SolrAuth] = None):
              context = SolrServerContext(SolrSingleServerHost(host), auth)
              return super().__new__(cls, context=context)
      client = SolrClient("localhost:8983", SolrBasicAuth("username", "password"))
    

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

solrstice-0.5.0.tar.gz (92.0 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

solrstice-0.5.0-cp38-abi3-win_amd64.whl (3.1 MB view details)

Uploaded CPython 3.8+Windows x86-64

solrstice-0.5.0-cp38-abi3-win32.whl (2.7 MB view details)

Uploaded CPython 3.8+Windows x86

solrstice-0.5.0-cp38-abi3-manylinux_2_28_x86_64.whl (3.9 MB view details)

Uploaded CPython 3.8+manylinux: glibc 2.28+ x86-64

solrstice-0.5.0-cp38-abi3-manylinux_2_28_s390x.whl (4.2 MB view details)

Uploaded CPython 3.8+manylinux: glibc 2.28+ s390x

solrstice-0.5.0-cp38-abi3-manylinux_2_28_ppc64le.whl (3.8 MB view details)

Uploaded CPython 3.8+manylinux: glibc 2.28+ ppc64le

solrstice-0.5.0-cp38-abi3-manylinux_2_28_armv7l.whl (3.6 MB view details)

Uploaded CPython 3.8+manylinux: glibc 2.28+ ARMv7l

solrstice-0.5.0-cp38-abi3-manylinux_2_28_aarch64.whl (3.8 MB view details)

Uploaded CPython 3.8+manylinux: glibc 2.28+ ARM64

solrstice-0.5.0-cp38-abi3-macosx_11_0_arm64.whl (3.3 MB view details)

Uploaded CPython 3.8+macOS 11.0+ ARM64

solrstice-0.5.0-cp38-abi3-macosx_10_12_x86_64.whl (3.5 MB view details)

Uploaded CPython 3.8+macOS 10.12+ x86-64

File details

Details for the file solrstice-0.5.0.tar.gz.

File metadata

  • Download URL: solrstice-0.5.0.tar.gz
  • Upload date:
  • Size: 92.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.7.0

File hashes

Hashes for solrstice-0.5.0.tar.gz
Algorithm Hash digest
SHA256 a792d48567c7e690d76cbdff20e3db1f05bacc1fb9cbd132448e517a19775038
MD5 07f945bddc63670f992db9735c5f18b9
BLAKE2b-256 affca38adfdebf7e42064929da11dfc490b41972ec1b1a5313f3788891d498ba

See more details on using hashes here.

File details

Details for the file solrstice-0.5.0-cp38-abi3-win_amd64.whl.

File metadata

  • Download URL: solrstice-0.5.0-cp38-abi3-win_amd64.whl
  • Upload date:
  • Size: 3.1 MB
  • Tags: CPython 3.8+, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.7.0

File hashes

Hashes for solrstice-0.5.0-cp38-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 285faafd308e2a941949d40ebd263fec8aa389ec743a5908e78aa00771da3df8
MD5 602ac7aa89fa1832075c659519b5fe93
BLAKE2b-256 a3bc73a1f6b9ee04da678af5e2d7fa8ceee81c7878964e80453c6435829852a3

See more details on using hashes here.

File details

Details for the file solrstice-0.5.0-cp38-abi3-win32.whl.

File metadata

  • Download URL: solrstice-0.5.0-cp38-abi3-win32.whl
  • Upload date:
  • Size: 2.7 MB
  • Tags: CPython 3.8+, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.7.0

File hashes

Hashes for solrstice-0.5.0-cp38-abi3-win32.whl
Algorithm Hash digest
SHA256 fe75f5f62f1da1395d35b4ad77cf222e6d6267034e7d3c5300a4ef3bfe025205
MD5 3968068eb7fe2bbf54c7e6b4da6eb978
BLAKE2b-256 57eb40daf8e03fe92fd623721d6cc1ad728aba8872c3530f396bacc01f75b625

See more details on using hashes here.

File details

Details for the file solrstice-0.5.0-cp38-abi3-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for solrstice-0.5.0-cp38-abi3-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 9cd3713855eabe4dd687c4accb1070e6dfc9ee983ba7532acc39208a6d605dd5
MD5 f7bc4b23735cae6264747d25165912b5
BLAKE2b-256 579dda2e2f51a70533778c02621caed5c4b4c8a4a901bf92590180b073434899

See more details on using hashes here.

File details

Details for the file solrstice-0.5.0-cp38-abi3-manylinux_2_28_s390x.whl.

File metadata

File hashes

Hashes for solrstice-0.5.0-cp38-abi3-manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 03f2eb8495349f8df463ebf988252e161189b9d80a67788a40553155de08e58c
MD5 3c6c1b8c0451db7862e6678cea6b9246
BLAKE2b-256 374c1f8f0c21dc6bdf1d8bf98e43ecaab358943e3f1ca53c6a7ce5fdf9f83bbe

See more details on using hashes here.

File details

Details for the file solrstice-0.5.0-cp38-abi3-manylinux_2_28_ppc64le.whl.

File metadata

File hashes

Hashes for solrstice-0.5.0-cp38-abi3-manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 5975ae23aa36c3d95e88e8d4bca11aa837c821d618095b511fd48f9b87ac630a
MD5 76beecde6337b705101bc22541865db0
BLAKE2b-256 70484ef035b59f05c9c33163cbeca3e238843003547b86446a43f5fb5be210d1

See more details on using hashes here.

File details

Details for the file solrstice-0.5.0-cp38-abi3-manylinux_2_28_armv7l.whl.

File metadata

File hashes

Hashes for solrstice-0.5.0-cp38-abi3-manylinux_2_28_armv7l.whl
Algorithm Hash digest
SHA256 7847403536f2ca71325251f92ad41762d6bd6381af6f9d2ada5bb8334c53060a
MD5 77508ff7b7f46a5f59fedace2d161ab5
BLAKE2b-256 3f9cafa3e895497396a3c0b8c9985178fc7f07868f674bf68e290310a0cb49fb

See more details on using hashes here.

File details

Details for the file solrstice-0.5.0-cp38-abi3-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for solrstice-0.5.0-cp38-abi3-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 aa62b847901731545f491024a5453c4dd1db17bff042e814b638ee4ce209404d
MD5 69ac81be0555f6eaece03769b7d5bd4c
BLAKE2b-256 3d29e0fa3af3e692bad6b51149b4e1fcccd732645d1d01bf1899777bc734c756

See more details on using hashes here.

File details

Details for the file solrstice-0.5.0-cp38-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for solrstice-0.5.0-cp38-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 fb6464a65972355d5e611182a21aab5af5d88afd7c97c1998f20e170a9539d73
MD5 d7acaba295a280e37335d6eb318bb128
BLAKE2b-256 07fe05b0eeb94f2567cac99cd13b0e51290c5b0705241b87b5724afbaa2b60c1

See more details on using hashes here.

File details

Details for the file solrstice-0.5.0-cp38-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for solrstice-0.5.0-cp38-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 36f31aca36e3217513f55f8f22dfc1dcc1cbce52156fdad38b935fdf496b55b9
MD5 b92f0195652be9f1a14621c146cff318
BLAKE2b-256 828cdbd0f138021d63bdf1be1ea27583142fd8efd98e1bb82c30283060de68e7

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page