Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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 CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ Import `pdb` in your file and use it:
import pdb

...
pdb.set_trace() # create a break point
pdb.set_trace() # create a break point
...
```

Expand Down
49 changes: 19 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,22 +63,22 @@ pip3 install meilisearch
```python
import meilisearch

client = meilisearch.Client('http://127.0.0.1:7700', 'masterKey')
client = meilisearch.Client("http://127.0.0.1:7700", "masterKey")

# An index is where the documents are stored.
index = client.index('movies')
index = client.index("movies")

documents = [
{ 'id': 1, 'title': 'Carol', 'genres': ['Romance', 'Drama'] },
{ 'id': 2, 'title': 'Wonder Woman', 'genres': ['Action', 'Adventure'] },
{ 'id': 3, 'title': 'Life of Pi', 'genres': ['Adventure', 'Drama'] },
{ 'id': 4, 'title': 'Mad Max: Fury Road', 'genres': ['Adventure', 'Science Fiction'] },
{ 'id': 5, 'title': 'Moana', 'genres': ['Fantasy', 'Action']},
{ 'id': 6, 'title': 'Philadelphia', 'genres': ['Drama'] },
{"id": 1, "title": "Carol", "genres": ["Romance", "Drama"]},
{"id": 2, "title": "Wonder Woman", "genres": ["Action", "Adventure"]},
{"id": 3, "title": "Life of Pi", "genres": ["Adventure", "Drama"]},
{"id": 4, "title": "Mad Max: Fury Road", "genres": ["Adventure", "Science Fiction"]},
{"id": 5, "title": "Moana", "genres": ["Fantasy", "Action"]},
{"id": 6, "title": "Philadelphia", "genres": ["Drama"]},
]

# If the index 'movies' does not exist, Meilisearch creates it when you first add the documents.
index.add_documents(documents) # => { "uid": 0 }
index.add_documents(documents) # => { "uid": 0 }
```

With the task `uid`, you can check the status (`enqueued`, `canceled`, `processing`, `succeeded` or `failed`) of your documents addition using the [task](https://www.meilisearch.com/docs/reference/api/tasks#get-tasks).
Expand All @@ -87,7 +87,7 @@ With the task `uid`, you can check the status (`enqueued`, `canceled`, `processi

```python
# Meilisearch is typo-tolerant:
index.search('caorl')
index.search("caorl")
```

Output:
Expand All @@ -114,10 +114,10 @@ All the supported options are described in the [search parameters](https://www.m

```python
index.search(
'phil',
{
'attributesToHighlight': ['*'],
}
"phil",
{
"attributesToHighlight": ["*"],
},
)
```

Expand Down Expand Up @@ -149,12 +149,7 @@ Hybrid search combines traditional keyword search with semantic search for more

```python
# Using hybrid search with the search method
index.search(
'action movie',
{
"hybrid": {"semanticRatio": 0.5, "embedder": "default"}
}
)
index.search("action movie", {"hybrid": {"semanticRatio": 0.5, "embedder": "default"}})
```

The `semanticRatio` parameter (between 0 and 1) controls the balance between keyword search and semantic search:
Expand All @@ -169,10 +164,7 @@ The `embedder` parameter specifies which configured embedder to use for the sema
If you want to enable filtering, you must add your attributes to the `filterableAttributes` index setting.

```py
index.update_filterable_attributes([
'id',
'genres'
])
index.update_filterable_attributes(["id", "genres"])
```

#### Custom Serializer for documents <!-- omit in toc -->
Expand Down Expand Up @@ -209,12 +201,7 @@ Note that Meilisearch will rebuild your index whenever you update `filterableAtt
Then, you can perform the search:

```py
index.search(
'wonder',
{
'filter': ['id > 1 AND genres = Action']
}
)
index.search("wonder", {"filter": ["id > 1 AND genres = Action"]})
```

```json
Expand Down Expand Up @@ -250,11 +237,13 @@ pip install meilisearch-python-sdk
import asyncio
from meilisearch_python_sdk import AsyncClient


async def main():
async with AsyncClient("http://127.0.0.1:7700", "masterKey") as client:
index = client.index("movies")
await index.search("wonder woman")


asyncio.run(main())
```

Expand Down
2 changes: 2 additions & 0 deletions meilisearch/models/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ class IndexStats(CamelBase):
is_indexing: bool
field_distribution: FieldDistribution
internal_database_sizes: dict[str, Any] | None = None
index_size: int | str | None = None
used_index_size: int | str | None = None

@field_validator("field_distribution", mode="before")
@classmethod
Expand Down
8 changes: 8 additions & 0 deletions tests/client/test_client_stats_meilisearch.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ def test_get_all_stats(client):
assert "indexes" in response
assert "indexUID" in response["indexes"]
assert "indexUID2" in response["indexes"]
assert "indexSize" in response["indexes"]["indexUID"]
assert "usedIndexSize" in response["indexes"]["indexUID"]


@pytest.mark.usefixtures("indexes_sample")
Expand Down Expand Up @@ -57,6 +59,12 @@ def test_get_all_stats_with_size_format(client):
isinstance(value, str) and HUMAN_SIZE_PATTERN.match(value)
for value in index_stats["internalDatabaseSizes"].values()
)
index_stats = response["indexes"]["indexUID"]
assert "indexSize" in index_stats and "usedIndexSize" in index_stats
assert isinstance(index_stats["indexSize"], str)
assert isinstance(index_stats["usedIndexSize"], str)
assert HUMAN_SIZE_PATTERN.match(index_stats["indexSize"])
assert HUMAN_SIZE_PATTERN.match(index_stats["usedIndexSize"])


@pytest.mark.usefixtures("indexes_sample")
Expand Down
8 changes: 8 additions & 0 deletions tests/index/test_index_stats_meilisearch.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ def test_get_stats_default(index_with_documents):
assert response.number_of_documents == 31
assert hasattr(response.field_distribution, "genre")
assert response.field_distribution.genre == 11
assert isinstance(response.index_size, int)
assert isinstance(response.used_index_size, int)
assert response.index_size > 0
assert response.used_index_size > 0


def test_get_stats_with_internal_database_sizes(index_with_documents):
Expand All @@ -43,6 +47,10 @@ def test_get_stats_with_size_format(index_with_documents):
isinstance(value, str) and HUMAN_SIZE_PATTERN.match(value)
for value in response.internal_database_sizes.values()
)
assert isinstance(response.index_size, str)
assert isinstance(response.used_index_size, str)
assert HUMAN_SIZE_PATTERN.match(response.index_size)
assert HUMAN_SIZE_PATTERN.match(response.used_index_size)


def test_get_stats_with_all_params(index_with_documents):
Expand Down