elasticsearch¶
ElasticCollection (EntryCollection)
¶
predefined_index: Dict[str, Any]
property
readonly
¶
Loads and returns the default pre-defined index.
__init__(self, name, resource_cls, resource_mapper, client=None)
special
¶
Initialize the ElasticCollection for the given parameters.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
name | str | The name of the collection. | required |
resource_cls | EntryResource | The type of entry resource that is stored by the collection. | required |
resource_mapper | BaseResourceMapper | A resource mapper object that handles aliases and format changes between deserialization and response. | required |
client | Optional[Elasticsearch] | A preconfigured Elasticsearch client. | None |
Source code in optimade/server/entry_collections/elasticsearch.py
def __init__(
self,
name: str,
resource_cls: EntryResource,
resource_mapper: BaseResourceMapper,
client: Optional["Elasticsearch"] = None,
):
"""Initialize the ElasticCollection for the given parameters.
Parameters:
name: The name of the collection.
resource_cls: The type of entry resource that is stored by the collection.
resource_mapper: A resource mapper object that handles aliases and
format changes between deserialization and response.
client: A preconfigured Elasticsearch client.
"""
super().__init__(
resource_cls=resource_cls,
resource_mapper=resource_mapper,
transformer=ElasticTransformer(mapper=resource_mapper),
)
self.client = client if client else CLIENT
self.name = name
# If we are creating a new collection from scratch, also create the index,
# otherwise assume it has already been created externally
if CONFIG.insert_test_data:
self.create_optimade_index()
count(self, *args, **kwargs)
¶
Returns the number of entries matching the query specified by the keyword arguments.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
kwargs | dict | Query parameters as keyword arguments. | {} |
Source code in optimade/server/entry_collections/elasticsearch.py
def count(self, *args, **kwargs) -> int:
raise NotImplementedError
create_elastic_index_from_mapper(resource_mapper, fields)
staticmethod
¶
Create a fallback elastic index based on a resource mapper.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
resource_mapper | BaseResourceMapper | The resource mapper to create the index for. | required |
fields | Iterable[str] | The list of fields to use in the index. | required |
Returns:
Type | Description |
---|---|
Dict[str, Any] | The |
Source code in optimade/server/entry_collections/elasticsearch.py
@staticmethod
def create_elastic_index_from_mapper(
resource_mapper: BaseResourceMapper, fields: Iterable[str]
) -> Dict[str, Any]:
"""Create a fallback elastic index based on a resource mapper.
Arguments:
resource_mapper: The resource mapper to create the index for.
fields: The list of fields to use in the index.
Returns:
The `body` parameter to pass to `client.indices.create(..., body=...)`.
"""
return {
"mappings": {
"doc": {
"properties": {
resource_mapper.get_optimade_field(field): {"type": "keyword"}
for field in fields
}
}
}
}
create_optimade_index(self)
¶
Load or create an index that can handle aliased OPTIMADE fields and attach it to the current client.
Source code in optimade/server/entry_collections/elasticsearch.py
def create_optimade_index(self) -> None:
"""Load or create an index that can handle aliased OPTIMADE fields and attach it
to the current client.
"""
body = self.predefined_index.get(self.name)
if body is None:
body = self.create_elastic_index_from_mapper(
self.resource_mapper, self.all_fields
)
properties = {}
for field in list(body["mappings"]["doc"]["properties"].keys()):
properties[self.resource_mapper.get_backend_field(field)] = body[
"mappings"
]["doc"]["properties"].pop(field)
body["mappings"]["doc"]["properties"] = properties
self.client.indices.create(index=self.name, body=body, ignore=400)
LOGGER.debug(f"Created Elastic index for {self.name!r} with body {body}")
insert(self, data)
¶
Add the given entries to the underlying database.
Warning
No validation is performed on the incoming data.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
data | List[optimade.models.entries.EntryResource] | The entry resource objects to add to the database. | required |
Source code in optimade/server/entry_collections/elasticsearch.py
def insert(self, data: List[EntryResource]) -> None:
"""Add the given entries to the underlying database.
Warning:
No validation is performed on the incoming data.
Arguments:
data: The entry resource objects to add to the database.
"""
def get_id(item):
if self.name == "links":
id_ = "%s-%s" % (item["id"], item["type"])
elif "id" in item:
id_ = item["id"]
elif "_id" in item:
# use the existing MongoDB ids in the test data
id_ = str(item["_id"])
else:
# ES will generate ids
id_ = None
item.pop("_id", None)
return id_
bulk(
self.client,
[
{
"_index": self.name,
"_id": get_id(item),
"_type": "doc",
"_source": item,
}
for item in data
],
)