Skip to content

Commit

Permalink
DE-743 | MDI/ZKD Indexes (#316)
Browse files Browse the repository at this point in the history
* DE-743 | initial commit

* fix: `format_index`

* remove `sparse` assertion

(zkd & mdi indexes don't support the `sparse` property`

* cleanup

* use `split` on `db_version`

allows us to test with a nightly build, e.g `3.12.0-NIGHTLY.20240116`
  • Loading branch information
aMahanna authored Feb 2, 2024
1 parent 474359e commit 9eeb3ec
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 1 deletion.
83 changes: 83 additions & 0 deletions arango/collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -1617,6 +1617,89 @@ def add_inverted_index(

return self._add_index(data)

def add_zkd_index(
self,
fields: Sequence[str],
field_value_types: str = "double",
name: Optional[str] = None,
unique: Optional[bool] = None,
in_background: Optional[bool] = None,
) -> Result[Json]:
"""Create a new ZKD Index.
:param fields: Document fields to index. Unlike for other indexes the
order of the fields does not matter.
:type fields: Sequence[str]
:param field_value_types: The type of the field values. The only allowed
value is "double" at the moment. Defaults to "double".
:type field_value_types: str
:param name: Optional name for the index.
:type name: str | None
:param unique: Whether the index is unique.
:type unique: bool | None
:param in_background: Do not hold the collection lock.
:type in_background: bool | None
:return: New index details.
:rtype: dict
:raise arango.exceptions.IndexCreateError: If create fails.
"""
data: Json = {
"type": "zkd",
"fields": fields,
"fieldValueTypes": field_value_types,
}

if unique is not None:
data["unique"] = unique
if name is not None:
data["name"] = name
if in_background is not None:
data["inBackground"] = in_background

return self._add_index(data)

def add_mdi_index(
self,
fields: Sequence[str],
field_value_types: str = "double",
name: Optional[str] = None,
unique: Optional[bool] = None,
in_background: Optional[bool] = None,
) -> Result[Json]:
"""Create a new MDI index, previously known as ZKD index. This method
is only usable with ArangoDB 3.12 and later.
:param fields: Document fields to index. Unlike for other indexes the
order of the fields does not matter.
:type fields: Sequence[str]
:param field_value_types: The type of the field values. The only allowed
value is "double" at the moment. Defaults to "double".
:type field_value_types: str
:param name: Optional name for the index.
:type name: str | None
:param unique: Whether the index is unique.
:type unique: bool | None
:param in_background: Do not hold the collection lock.
:type in_background: bool | None
:return: New index details.
:rtype: dict
:raise arango.exceptions.IndexCreateError: If create fails.
"""
data: Json = {
"type": "mdi",
"fields": fields,
"fieldValueTypes": field_value_types,
}

if unique is not None:
data["unique"] = unique
if name is not None:
data["name"] = name
if in_background is not None:
data["inBackground"] = in_background

return self._add_index(data)

def delete_index(self, index_id: str, ignore_missing: bool = False) -> Result[bool]:
"""Delete an index.
Expand Down
2 changes: 2 additions & 0 deletions arango/formatter.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ def format_index(body: Json) -> Json:
result["writebuffer_active"] = body["writebufferActive"]
if "writebufferSizeMax" in body:
result["writebuffer_max_size"] = body["writebufferSizeMax"]
if "fieldValueTypes" in body:
result["field_value_types"] = body["fieldValueTypes"]

return verify_format(body, result)

Expand Down
2 changes: 1 addition & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ def pytest_configure(config):
global_data.username = username
global_data.password = password
global_data.db_name = tst_db_name
global_data.db_version = version.parse(db_version)
global_data.db_version = version.parse(db_version.split("-")[0])
global_data.sys_db = sys_db
global_data.tst_db = tst_db
global_data.bad_db = bad_db
Expand Down
61 changes: 61 additions & 0 deletions tests/test_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,67 @@ def test_add_inverted_index(icol, enterprise, db_version):
icol.delete_index(result["id"])


def test_add_zkd_index(icol, db_version):
result = icol.add_zkd_index(
name="zkd_index",
fields=["x", "y", "z"],
field_value_types="double",
in_background=False,
unique=False,
)

expected_index = {
"name": "zkd_index",
"type": "zkd",
"fields": ["x", "y", "z"],
"new": True,
"unique": False,
}

for key, value in expected_index.items():
assert result[key] == value

assert result["id"] in extract("id", icol.indexes())

with assert_raises(IndexCreateError) as err:
icol.add_zkd_index(field_value_types="integer", fields=["x", "y", "z"])
assert err.value.error_code == 10

icol.delete_index(result["id"])


def test_add_mdi_index(icol, db_version):
if db_version < version.parse("3.12.0"):
pytest.skip("MDI indexes are usable with 3.12+ only")

result = icol.add_mdi_index(
name="mdi_index",
fields=["x", "y", "z"],
field_value_types="double",
in_background=False,
unique=True,
)

expected_index = {
"name": "mdi_index",
"type": "mdi",
"fields": ["x", "y", "z"],
"new": True,
"unique": True,
}

for key, value in expected_index.items():
assert result[key] == value

assert result["id"] in extract("id", icol.indexes())

with assert_raises(IndexCreateError) as err:
icol.add_mdi_index(field_value_types="integer", fields=["x", "y", "z"])
assert err.value.error_code == 10

icol.delete_index(result["id"])


def test_delete_index(icol, bad_col):
old_indexes = set(extract("id", icol.indexes()))
icol.add_hash_index(["attr3", "attr4"], unique=True)
Expand Down

0 comments on commit 9eeb3ec

Please sign in to comment.