Skip to content

Make add_index public #321

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
May 29, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ db = client.db("test", username="root", password="passwd")
students = db.create_collection("students")

# Add a hash index to the collection.
students.add_hash_index(fields=["name"], unique=True)
students.add_index({'type': 'hash', 'fields': ['name'], 'unique': True})

# Insert new documents into the collection.
students.insert({"name": "jane", "age": 39})
Expand Down
126 changes: 33 additions & 93 deletions arango/collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from numbers import Number
from typing import List, Optional, Sequence, Tuple, Union
from warnings import warn

from arango.api import ApiGroup
from arango.connection import Connection
Expand Down Expand Up @@ -1259,10 +1260,11 @@ def response_handler(resp: Response) -> Json:

return self._execute(request, response_handler)

def _add_index(self, data: Json) -> Result[Json]:
"""Helper method for creating a new index.
def add_index(self, data: Json) -> Result[Json]:
"""Create an index.

:param data: Index data.
:param data: Index data. Must contain a "type" field
with the index type.
:type data: dict
:return: New index details.
:rtype: dict
Expand Down Expand Up @@ -1311,6 +1313,9 @@ def add_hash_index(
:rtype: dict
:raise arango.exceptions.IndexCreateError: If create fails.
"""
m = "add_hash_index is deprecated. Using add_index with {'type': 'hash'} instead." # noqa: E501
warn(m, DeprecationWarning, stacklevel=2)

data: Json = {"type": "hash", "fields": fields}

if unique is not None:
Expand All @@ -1324,7 +1329,7 @@ def add_hash_index(
if in_background is not None:
data["inBackground"] = in_background

return self._add_index(data)
return self.add_index(data)

def add_skiplist_index(
self,
Expand Down Expand Up @@ -1355,6 +1360,9 @@ def add_skiplist_index(
:rtype: dict
:raise arango.exceptions.IndexCreateError: If create fails.
"""
m = "add_skiplist_index is deprecated. Using add_index with {'type': 'skiplist'} instead." # noqa: E501
warn(m, DeprecationWarning, stacklevel=2)

data: Json = {"type": "skiplist", "fields": fields}

if unique is not None:
Expand All @@ -1368,7 +1376,7 @@ def add_skiplist_index(
if in_background is not None:
data["inBackground"] = in_background

return self._add_index(data)
return self.add_index(data)

def add_geo_index(
self,
Expand Down Expand Up @@ -1400,6 +1408,9 @@ def add_geo_index(
:rtype: dict
:raise arango.exceptions.IndexCreateError: If create fails.
"""
m = "add_geo_index is deprecated. Using add_index with {'type': 'geo'} instead." # noqa: E501
warn(m, DeprecationWarning, stacklevel=2)

data: Json = {"type": "geo", "fields": fields}

if geo_json is not None:
Expand All @@ -1411,7 +1422,7 @@ def add_geo_index(
if legacyPolygons is not None:
data["legacyPolygons"] = legacyPolygons

return self._add_index(data)
return self.add_index(data)

def add_fulltext_index(
self,
Expand All @@ -1436,6 +1447,9 @@ def add_fulltext_index(
:rtype: dict
:raise arango.exceptions.IndexCreateError: If create fails.
"""
m = "add_fulltext_index is deprecated. Using add_index with {'type': 'fulltext'} instead." # noqa: E501
warn(m, DeprecationWarning, stacklevel=2)

data: Json = {"type": "fulltext", "fields": fields}

if min_length is not None:
Expand All @@ -1445,7 +1459,7 @@ def add_fulltext_index(
if in_background is not None:
data["inBackground"] = in_background

return self._add_index(data)
return self.add_index(data)

def add_persistent_index(
self,
Expand Down Expand Up @@ -1488,6 +1502,9 @@ def add_persistent_index(
:rtype: dict
:raise arango.exceptions.IndexCreateError: If create fails.
"""
m = "add_persistent_index is deprecated. Using add_index with {'type': 'persistent'} instead." # noqa: E501
warn(m, DeprecationWarning, stacklevel=2)

data: Json = {"type": "persistent", "fields": fields}

if unique is not None:
Expand All @@ -1503,7 +1520,7 @@ def add_persistent_index(
if cacheEnabled is not None:
data["cacheEnabled"] = cacheEnabled

return self._add_index(data)
return self.add_index(data)

def add_ttl_index(
self,
Expand All @@ -1526,14 +1543,17 @@ def add_ttl_index(
:rtype: dict
:raise arango.exceptions.IndexCreateError: If create fails.
"""
m = "add_ttl_index is deprecated. Using add_index with {'type': 'ttl'} instead." # noqa: E501
warn(m, DeprecationWarning, stacklevel=2)

data: Json = {"type": "ttl", "fields": fields, "expireAfter": expiry_time}

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

return self._add_index(data)
return self.add_index(data)

def add_inverted_index(
self,
Expand Down Expand Up @@ -1588,6 +1608,9 @@ def add_inverted_index(
:rtype: dict
:raise arango.exceptions.IndexCreateError: If create fails.
"""
m = "add_inverted_index is deprecated. Using add_index with {'type': 'inverted'} instead." # noqa: E501
warn(m, DeprecationWarning, stacklevel=2)

data: Json = {"type": "inverted", "fields": fields}

if name is not None:
Expand Down Expand Up @@ -1617,90 +1640,7 @@ def add_inverted_index(
if cache is not None:
data["cache"] = cache

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)
return self.add_index(data)

def delete_index(self, index_id: str, ignore_missing: bool = False) -> Result[bool]:
"""Delete an index.
Expand Down
26 changes: 18 additions & 8 deletions docs/indexes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,36 @@ on fields ``_from`` and ``_to``. For more information on indexes, refer to
cities.indexes()

# Add a new hash index on document fields "continent" and "country".
index = cities.add_hash_index(fields=['continent', 'country'], unique=True)
hash_index = {'type': 'hash', 'fields': ['continent', 'country'], 'unique': True}
index = cities.add_index(hash_index)

# Add new fulltext indexes on fields "continent" and "country".
index = cities.add_fulltext_index(fields=['continent'])
index = cities.add_fulltext_index(fields=['country'])
index = cities.add_index({'type': 'fulltext', 'fields': ['continent']})
index = cities.add_index({'type': 'fulltext', 'fields': ['country']})

# Add a new skiplist index on field 'population'.
index = cities.add_skiplist_index(fields=['population'], sparse=False)
skiplist_index = {'type': 'skiplist', 'fields': ['population'], 'sparse': False}
index = cities.add_index(skiplist_index)

# Add a new geo-spatial index on field 'coordinates'.
index = cities.add_geo_index(fields=['coordinates'])
geo_index = {'type': 'geo', 'fields': ['coordinates']}
index = cities.add_index(geo_index)

# Add a new persistent index on field 'currency'.
index = cities.add_persistent_index(fields=['currency'], sparse=True)
persistent_index = {'type': 'persistent', 'fields': ['currency'], 'sparse': True}
index = cities.add_index(persistent_index)

# Add a new TTL (time-to-live) index on field 'currency'.
index = cities.add_ttl_index(fields=['currency'], expiry_time=200)
ttl_index = {'type': 'ttl', 'fields': ['currency'], 'expireAfter': 200}
index = cities.add_index(ttl_index)

# Add MDI (multi-dimensional) index on field 'x' and 'y'.
mdi_index = {'type': 'mdi', 'fields': ['x', 'y'], 'field_value_types': ['double']}
index = cities.add_index(mdi_index)

# Indexes may be added with a name that can be referred to in AQL queries.
index = cities.add_hash_index(fields=['country'], name='my_hash_index')
hash_index = {'type': 'hash', 'fields': ['country'], 'unique': True, 'name': 'my_hash_index'}
index = cities.add_index(hash_index)

# Delete the last index from the collection.
cities.delete_index(index['id'])
Expand Down
2 changes: 1 addition & 1 deletion docs/overview.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Here is an example showing how **python-arango** client can be used:
students = db.create_collection('students')

# Add a hash index to the collection.
students.add_hash_index(fields=['name'], unique=False)
students.add_index({'type': 'hash', 'fields': ['name'], 'unique': True})

# Truncate the collection.
students.truncate()
Expand Down
6 changes: 3 additions & 3 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,9 @@ def pytest_configure(config):
col_name = generate_col_name()
tst_col = tst_db.create_collection(col_name, edge=False)

tst_col.add_skiplist_index(["val"])
tst_col.add_fulltext_index(["text"])
geo_index = tst_col.add_geo_index(["loc"])
tst_col.add_index({"type": "skiplist", "fields": ["val"]})
tst_col.add_index({"type": "fulltext", "fields": ["text"]})
geo_index = tst_col.add_index({"type": "geo", "fields": ["loc"]})

# Create a legacy edge collection for testing.
icol_name = generate_col_name()
Expand Down
3 changes: 2 additions & 1 deletion tests/test_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,8 @@ def create_and_delete_collection(db, name):
assert col.name == name
assert db.has_collection(name) is True

index_id = col.add_hash_index(fields=["foo"])["name"]
hash_index = {"type": "hash", "fields": ["foo"]}
index_id = col.add_index(hash_index)["name"]
assert index_id == col.indexes()[-1]["name"]
assert col.delete_index(index_id) is True

Expand Down
3 changes: 2 additions & 1 deletion tests/test_document.py
Original file line number Diff line number Diff line change
Expand Up @@ -1463,7 +1463,8 @@ def test_document_find_in_box(db, col, bad_col, geo, cluster):
)

# Test find_in_box with non-geo index
non_geo = col.add_hash_index(fields=["loc"])
hash_index = {"type": "hash", "fields": ["loc"]}
non_geo = col.add_index(hash_index)
with assert_raises(ValueError) as err:
col.find_in_box(
latitude1=0,
Expand Down
Loading