https://github.com/pukkaone/graphql-search
GraphQL server for search
https://github.com/pukkaone/graphql-search
elasticsearch graphql graphql-java graphql-server spring-boot
Last synced: 16 days ago
JSON representation
GraphQL server for search
- Host: GitHub
- URL: https://github.com/pukkaone/graphql-search
- Owner: pukkaone
- License: apache-2.0
- Created: 2025-09-01T04:03:24.000Z (8 months ago)
- Default Branch: main
- Last Pushed: 2025-11-16T10:39:13.000Z (6 months ago)
- Last Synced: 2025-11-16T12:17:30.978Z (6 months ago)
- Topics: elasticsearch, graphql, graphql-java, graphql-server, spring-boot
- Language: Kotlin
- Homepage:
- Size: 42 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 2
-
Metadata Files:
- Readme: README.adoc
- License: LICENSE.txt
Awesome Lists containing this project
README
= GraphQL Server For Search
An example server exposes a GraphQL API for search indices by following a schema-first approach.
Starting from a schema that defines the structure of the documents in search indices, the server
generates:
* Elasticsearch index mappings, and
* GraphQL schema with additional types needed to execute mutations and queries on search indices.
== API Version
An API version implements a different generation of a GraphQL API within a single server.
A GraphQL schema defines the types and operations implemented by an API version.
The server exposes an HTTP endpoint for each API version at the URL paths:
----
{server.servlet.context-path}/graphql/{api-version}
----
== Proto Schema
A proto schema is a schema from which other schema are generated.
It is written in the GraphQL schema definition language.
The `src/main/resources/search/` directory contains a subdirectory for each API version.
The schema files under a API version subdirectory define the proto schema for that API version.
=== Directives
Directives provide information about how to generate the other schema.
The `@document` directive indicates the annotated object type is the root object of the document to
be put in a search index.
[source,graphql]
----
type Transaction @document {
----
The `@id` directive indicates the annotated field uniquely identifies the document in a search
index.
This is the document ID used to put a document into a search index.
[source,graphql]
----
transaction_urn: ID! @id
----
The `@searchable` directive indicates the annotated field can be queried in a search.
[source,graphql]
----
city: String! @searchable
----
By default, the server translates the `ID` scalar type to the `"keyword"` mapping type, and the
`String` scalar type to the `"text"` mapping type.
The `type` argument can change the mapping type.
----
product_code: String! @searchable(type: "keyword")
----
By default, the server translates an object type definition to a mapping with type `"object"`.
The `type` argument can change the mapping type to `"nested"`.
[source,graphql]
----
type Listing @searchable(type: "nested") {
----
== Search Schema
The search schema is generated from the proto schema.
This is the schema exposed by the GraphQL API.
=== Create an index and assign an alias to it
[source,graphql]
----
mutation {
createIndexWithAlias(
type: "Transaction"
index: "transaction-1"
alias: "transaction-write"
)
}
----
=== Put a document into a search index
[source,graphql]
----
mutation put {
putTransaction(
index: "transaction-write"
documents: {
transaction_urn: "transaction:1"
listing: {
listing_urn: "listing:2"
description: "description"
reserve_price: 2
valuation_price: 1
}
property: {
property_urn: "property:3"
location: {
address: {
line: "9641 Sunset Blvd"
city: "Beverly Hills"
state: "CA"
postal_code: "90210"
country: "US"
}
position: {
lat: 34.084925
lon: -118.413516
}
}
bathrooms: 2
bedrooms: 3
}
}
)
}
----
=== Search for documents
[source,graphql]
----
query search {
transactionSearch(
index: "transaction"
filter: {
property: {
location: {
address: {
state: {
eq: "CA"
}
}
}
}
}
sort: {
field: "property.bedrooms"
direction: ASC
}
) {
edges {
node {
transaction_urn
}
}
pageInfo {
endCursor
hasNextPage
}
}
}
----
=== Group documents into buckets
[source,graphql]
----
query aggregate {
transactionSearch(
index: "transaction"
filter: {
property: {
location: {
address: {
state: {
eq: "CA"
}
}
}
}
}
groupBy: {
property: {
bedrooms: {
terms: {
first: 10
}
}
}
}
) {
groupBy {
property {
bedrooms {
key
count
}
}
}
}
}
----
==== Filter Operators
The following filter operators are supported:
[cols="1,3"]
|===
| Operator | Description
| `and:` | All of the conditions must be true
| `or:` | At least one of the conditions must be true
| `not:` | All of the conditions must be false
| `contains:` | A term analyzed from the field value is a term in the list
| `eq:` | Equal to
| `in:` | The field value is a value in the list
| `gt:` | Greater than
| `gte:` | Greater than or equal to
| `lt:` | Less than
| `lte:` | Less than or equal to
| `exists:` | Whether the field has a value
| `geoDistance:` | The GeoPoint field value is within the given radius from the given center
|===