Graphene Elasticsearch (DSL) integration
Project description
Elasticsearch (DSL) integration for Graphene.
Prerequisites
Graphene 2.x. Support for Graphene 1.x is not planned, but might be considered.
Python 3.6, 3.7. Support for Python 2 is not intended.
Elasticsearch 6.x, 7.x. Support for Elasticsearch 5.x is not intended.
Main features and highlights
Implemented ElasticsearchConnectionField and ElasticsearchObjectType are the core classes to work with graphene.
Pluggable backends for searching, filtering, ordering, etc. Don’t like existing ones? Extend or write your own.
Implemented search backend.
Implemented filter backend.
See the Road-map for what’s yet planned to implemented.
Documentation
Documentation is available on Read the Docs.
Installation
For installing graphene-elastic, just run this command in your shell:
pip install graphene-elastic
Examples
Install requirements
pip install -r examples/requirements.txt
Populate sample data
The following command will create indexes for User and Post documents and populate them with sample data:
./scripts/populate_elasticsearch_data.sh
Sample document definition
search_index/documents/post.py
See examples/search_index/documents/post.py for full example.
import datetime
from elasticsearch_dsl import (
Boolean,
Date,
Document,
InnerDoc,
Keyword,
Nested,
Text,
Integer,
)
class Comment(InnerDoc):
author = Text(fields={'raw': Keyword()})
content = Text(analyzer='snowball')
created_at = Date()
def age(self):
return datetime.datetime.now() - self.created_at
class Post(Document):
title = Text(
fields={'raw': Keyword()}
)
content = Text()
created_at = Date()
published = Boolean()
category = Text(
fields={'raw': Keyword()}
)
comments = Nested(Comment)
num_views = Integer()
class Index:
name = 'blog_post'
settings = {
'number_of_shards': 1,
'number_of_replicas': 1,
'blocks': {'read_only_allow_delete': None},
}
def add_comment(self, author, content):
self.comments.append(
Comment(
author=author,
content=content,
created_at=datetime.datetime.now()
)
)
def save(self, ** kwargs):
self.created_at = datetime.datetime.now()
return super().save(** kwargs)
Sample apps
Sample Flask app
Run the sample Flask app:
./scripts/run_flask.sh
Open Flask graphiql client
http://127.0.0.1:8001/graphql
Sample Django app
Run the sample Django app:
./scripts/run_django.sh runserver
Open Flask graphiql client
http://127.0.0.1:8000/graphql
ConnectionField example
ConnectionField is more flexible. It uses filter backends which you can tie to your needs the way you want in a declarative way.
import graphene
from graphene_elastic import (
ElasticsearchObjectType,
ElasticsearchConnectionField,
)
from graphene_elastic.filter_backends import (
FilteringFilterBackend,
SearchFilterBackend,
)
from graphene_elastic.constants import (
LOOKUP_FILTER_PREFIX,
LOOKUP_FILTER_TERM,
LOOKUP_FILTER_TERMS,
LOOKUP_FILTER_WILDCARD,
LOOKUP_QUERY_EXCLUDE,
LOOKUP_QUERY_IN,
)
# Object type definition
class Post(ElasticsearchObjectType):
class Meta(object):
document = PostDocument
interfaces = (Node,)
filter_backends = [
FilteringFilterBackend,
SearchFilterBackend,
]
filter_fields = {
'title': {
'field': 'title.raw',
'lookups': [
LOOKUP_FILTER_TERM,
LOOKUP_FILTER_TERMS,
LOOKUP_FILTER_PREFIX,
LOOKUP_FILTER_WILDCARD,
LOOKUP_QUERY_IN,
LOOKUP_QUERY_EXCLUDE,
],
'default_lookup': LOOKUP_FILTER_TERM,
},
'category': 'category.raw',
'num_views': 'num_views',
}
search_fields = {
'title': {'boost': 4},
'content': {'boost': 2},
'category': None,
}
# Query definition
class Query(graphene.ObjectType):
all_post_documents = ElasticsearchConnectionField(Post)
# Schema definition
schema = graphene.Schema(query=Query)
Filter
Since we didn’t specify any lookups on category, by default all lookups are available. Default lookup would be LOOKUP_FILTER_TERM.
query PostsQuery {
allPostDocuments(filter:{category:{query:["Elastic"]}}) {
edges {
node {
id
title
category
content
createdAt
comments
}
}
}
}
But, we could use another lookup by adding it to the query:
query PostsQuery {
allPostDocuments(filter:{category:{query:["tic"], lookup:ENDSWITH}}) {
edges {
node {
id
title
category
content
createdAt
comments
}
}
}
}
Or apply a range query in addition to filtering:
{
allPostDocuments(filter:{
category:{query:"Python"},
numViews:{lookup:RANGE, lower:"1000", upper:"2000"}
}) {
edges {
node {
category
title
comments
numViews
}
}
}
}
Search
query {
allPostDocuments(
search:{title:{query:"Release", boost:1}, content:{query:"Box"}}}
) {
edges {
node {
category
title
comments
}
}
}
}
Road-map
Road-map and development plans.
Lots of features are planned to be released in the upcoming Beta releases:
Ordering backend
Geo-spatial backend
Aggregations (faceted search) backend
Post-filter backend
Nested backend
Highlight backend
Suggester backend
Global aggregations backend
More-like-this backend
Complex search backends, such as Simple query search
Source filter backend
Stay tuned or reach out if you want to help.
Testing
Project is covered with tests.
To test with all supported Python versions type:
tox
To test against specific environment, type:
tox -e py37
To test just your working environment type:
./runtests.py
pip install -r examples/requirements/test.txt
Debugging
For development purposes, you could use the flask app (easy to debug). Standard pdb works (import pdb; pdb.set_trace()). If ipdb does not work well for you, use ptpdb does.
Writing documentation
Keep the following hierarchy.
=====
title
=====
header
======
sub-header
----------
sub-sub-header
~~~~~~~~~~~~~~
sub-sub-sub-header
^^^^^^^^^^^^^^^^^^
sub-sub-sub-sub-header
++++++++++++++++++++++
sub-sub-sub-sub-sub-header
**************************
License
GPL-2.0-only OR LGPL-2.1-or-later
Support
For any issues contact me at the e-mail given in the Author section.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for graphene_elastic-0.0.4-py2.py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 18e187e9bb86e5aa4cd123e616c275849b5071407921a1d3b291ce607847e9c6 |
|
MD5 | 7f718c0f2722045da1f9072ef76c7dc5 |
|
BLAKE2b-256 | 70d94242ec51170c176515bdb06db4210493d93b8ed2f753189d5c58a91c544d |