Repository: deepset-ai/haystack

Issue:
Issues with Weaviate documentstore
document_store.write_documents() method causes error when document_store is weaviate(1.4.0)

```
>>> document_store.write_documents(docs)
  0%|                                                                         | 0/61 [00:00<?, ?it/s]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/dwight/Desktop/haystack/10-Oct/haystack/haystack/document_store/weaviate.py", line 390, in write_documents
    self._update_schema(property, index)
  File "/home/dwight/Desktop/haystack/10-Oct/haystack/haystack/document_store/weaviate.py", line 319, in _update_schema
    self.weaviate_client.schema.property.create(index, property_dict)
  File "/home/dwight/miniconda3/envs/hay38/lib/python3.8/site-packages/weaviate/schema/properties/crud_properties.py", line 76, in create
    raise UnexpectedStatusCodeException("Add property to class", response)
weaviate.exceptions.UnexpectedStatusCodeException: Add property to class! Unexpected status code: 422, with response body: {'error': [{'message': "'_split_id' is not a valid property name"}]}
```

To replicate the issue, clone latest repo and run the Basic QA pipeline colab tutorial with weaviate(since weaviate runs as docker I just used python shell after running docker container). 


Discussion:
Hi @advaitdeshmukh! I tried to replicate your issue. I also got an error, but my error message is different:
```
Traceback (most recent call last):
  File "/Users/bogdan/Repositories/haystack/haystack/document_store/weaviate.py", line 393, in write_documents
    docs_batch.add(_doc, class_name=index, uuid=doc_id, vector=vector)
  File "/opt/homebrew/Caskroom/miniforge/base/envs/haystack/lib/python3.9/site-packages/weaviate/batch/requests.py", line 193, in add
    batch_item["id"] = get_valid_uuid(uuid)
  File "/opt/homebrew/Caskroom/miniforge/base/envs/haystack/lib/python3.9/site-packages/weaviate/util.py", line 248, in get_valid_uuid
    raise ValueError("Not valid 'uuid' or 'uuid' can not be extracted from value")
ValueError: Not valid 'uuid' or 'uuid' can not be extracted from value
```
@tholor 
It seems that Weaviate only allows document ids in the format of UUIDs. Right now, we are creating hashes as document ids if no ids are supplied. We would probably need to create uuids instead. Also, what should we do in case the user supplies their own ids? We would definitely need to check if the supplied ids are in the correct format, otherwise, we would always trigger the error above for custom ids.
We started some work in #1242 - let's pick this up again and fix it. 
@bogdankostic  huh. I wonder why we are getting different error messages. Could that be related to the fact that I'm using python 3.8?

Resolving patch:
diff --git a/haystack/document_stores/weaviate.py b/haystack/document_stores/weaviate.py
--- a/haystack/document_stores/weaviate.py
+++ b/haystack/document_stores/weaviate.py
@@ -1,3 +1,6 @@
+import hashlib
+import re
+import uuid
 from typing import Dict, Generator, List, Optional, Union
 
 import logging
@@ -13,6 +16,7 @@
 
 
 logger = logging.getLogger(__name__)
+UUID_PATTERN = re.compile(r'^[\da-f]{8}-([\da-f]{4}-){3}[\da-f]{12}$', re.IGNORECASE)
 
 
 class WeaviateDocumentStore(BaseDocumentStore):
@@ -24,7 +28,8 @@ class WeaviateDocumentStore(BaseDocumentStore):
     Some of the key differences in contrast to FAISS & Milvus:
     1. Stores everything in one place: documents, meta data and vectors - so less network overhead when scaling this up
     2. Allows combination of vector search and scalar filtering, i.e. you can filter for a certain tag and do dense retrieval on that subset 
-    3. Has less variety of ANN algorithms, as of now only HNSW.  
+    3. Has less variety of ANN algorithms, as of now only HNSW.
+    4. Requires document ids to be in uuid-format. If wrongly formatted ids are provided at indexing time they will be replaced with uuids automatically.
 
     Weaviate python client is used to connect to the server, more details are here
     https://weaviate-python-client.readthedocs.io/en/docs/weaviate.html
@@ -119,7 +124,7 @@ def __init__(
                 f"Initial connection to Weaviate failed. Make sure you run Weaviate instance "
                 f"at `{weaviate_url}` and that it has finished the initial ramp up (can take > 30s)."
             )
-        self.index = index
+        self.index = self._sanitize_index_name(index)
         self.embedding_dim = embedding_dim
         self.content_field = content_field
         self.name_field = name_field
@@ -132,6 +137,15 @@ def __init__(
         self.duplicate_documents = duplicate_documents
 
         self._create_schema_and_index_if_not_exist(self.index)
+        self.uuid_format_warning_raised = False
+
+    def _sanitize_index_name(self, index: Optional[str]) -> Optional[str]:
+        if index is None:
+            return None
+        elif "_" in index:
+            return ''.join(x.capitalize() for x in index.split('_'))
+        else:
+            return index[0].upper() + index[1:]
 
     def _create_schema_and_index_if_not_exist(
         self,
@@ -141,7 +155,7 @@ def _create_schema_and_index_if_not_exist(
         Create a new index (schema/class in Weaviate) for storing documents in case if an 
         index (schema) with the name doesn't exist already.
         """
-        index = index or self.index
+        index = self._sanitize_index_name(index) or self.index
 
         if self.custom_schema:
             schema = self.custom_schema
@@ -238,7 +252,7 @@ def _create_document_field_map(self) -> Dict:
         }
 
     def get_document_by_id(self, id: str, index: Optional[str] = None) -> Optional[Document]:
-        """Fetch a document by specifying its text id string"""
+        """Fetch a document by specifying its uuid string"""
         # Sample result dict from a get method
         '''{'class': 'Document',
          'creationTimeUnix': 1621075584724,
@@ -247,8 +261,11 @@ def get_document_by_id(self, id: str, index: Optional[str] = None) -> Optional[D
           'name': 'name_5',
           'content': 'text_5'},
          'vector': []}'''
-        index = index or self.index
+        index = self._sanitize_index_name(index) or self.index
         document = None
+
+        id = self._sanitize_id(id=id, index=index)
+
         result = self.weaviate_client.data_object.get_by_id(id, with_vector=True)
         if result:
             document = self._convert_weaviate_result_to_document(result, return_embedding=True)
@@ -257,23 +274,40 @@ def get_document_by_id(self, id: str, index: Optional[str] = None) -> Optional[D
     def get_documents_by_id(self, ids: List[str], index: Optional[str] = None,
                             batch_size: int = 10_000) -> List[Document]:
         """
-        Fetch documents by specifying a list of text id strings.
+        Fetch documents by specifying a list of uuid strings.
         """
-        index = index or self.index
+        index = self._sanitize_index_name(index) or self.index
         documents = []
         #TODO: better implementation with multiple where filters instead of chatty call below?
         for id in ids:
+            id = self._sanitize_id(id=id, index=index)
             result = self.weaviate_client.data_object.get_by_id(id, with_vector=True)
             if result:
                 document = self._convert_weaviate_result_to_document(result, return_embedding=True)
                 documents.append(document)
         return documents
 
+    def _sanitize_id(self, id: str, index: Optional[str] = None) -> str:
+        """
+        Generate a valid uuid if the provided id is not in uuid format.
+        Two documents with the same provided id and index name will get the same uuid.
+        """
+        index = self._sanitize_index_name(index) or self.index
+        if not UUID_PATTERN.match(id):
+            hashed_id = hashlib.sha256((id+index).encode('utf-8')) #type: ignore
+            generated_uuid = str(uuid.UUID(hashed_id.hexdigest()[::2]))
+            if not self.uuid_format_warning_raised:
+                logger.warning(
+                    f"Document id {id} is not in uuid format. Such ids will be replaced by uuids, in this case {generated_uuid}.")
+                self.uuid_format_warning_raised = True
+            id = generated_uuid
+        return id
+
     def _get_current_properties(self, index: Optional[str] = None) -> List[str]:
         """
         Get all the existing properties in the schema.
         """
-        index = index or self.index
+        index = self._sanitize_index_name(index) or self.index
         cur_properties = []
         for class_item in self.weaviate_client.schema.get()['classes']:
             if class_item['class'] == index:
@@ -308,7 +342,7 @@ def _update_schema(self, new_prop:str, index: Optional[str] = None):
         """
         Updates the schema with a new property.
         """
-        index = index or self.index
+        index = self._sanitize_index_name(index) or self.index
         property_dict = {
             "dataType": [
                 "string"
@@ -330,8 +364,7 @@ def write_documents(
         """
         Add new documents to the DocumentStore.
 
-        :param documents: List of `Dicts` or List of `Documents`. Passing an Embedding/Vector is mandatory in case weaviate is not
-                        configured with a module. If a module is configured, the embedding is automatically generated by Weaviate.
+        :param documents: List of `Dicts` or List of `Documents`. A dummy embedding vector for each document is automatically generated if it is not provided. The document id needs to be in uuid format. Otherwise a correctly formatted uuid will be automatically generated based on the provided id.
         :param index: index name for storing the docs and metadata
         :param batch_size: When working with large number of documents, batching can help reduce memory footprint.
         :param duplicate_documents: Handle duplicates document based on parameter options.
@@ -343,7 +376,7 @@ def write_documents(
         :raises DuplicateDocumentError: Exception trigger on duplicate document
         :return: None
         """
-        index = index or self.index
+        index = self._sanitize_index_name(index) or self.index
         self._create_schema_and_index_if_not_exist(index)
         field_map = self._create_document_field_map()
 
@@ -360,9 +393,30 @@ def write_documents(
         current_properties = self._get_current_properties(index)
 
         document_objects = [Document.from_dict(d, field_map=field_map) if isinstance(d, dict) else d for d in documents]
+
+        # Weaviate has strict requirements for what ids can be used.
+        # We check the id format and sanitize it if no uuid was provided.
+        # Duplicate document ids will be mapped to the same generated uuid.
+        for do in document_objects:
+            do.id = self._sanitize_id(id=do.id, index=index)
+
         document_objects = self._handle_duplicate_documents(documents=document_objects,
                                                             index=index,
                                                             duplicate_documents=duplicate_documents)
+
+        # Weaviate requires that documents contain a vector in order to be indexed. These lines add a
+        # dummy vector so that indexing can still happen
+        dummy_embed_warning_raised = False
+        for do in document_objects:
+            if do.embedding is None:
+                dummy_embedding = np.random.rand(self.embedding_dim).astype(np.float32)
+                do.embedding = dummy_embedding
+                if not dummy_embed_warning_raised:
+                    logger.warning("No embedding found in Document object being written into Weaviate. A dummy "
+                                 "embedding is being supplied so that indexing can still take place. This "
+                                 "embedding should be overwritten in order to perform vector similarity searches.")
+                    dummy_embed_warning_raised = True
+
         batched_documents = get_batches_from_generator(document_objects, batch_size)
         with tqdm(total=len(document_objects), disable=not self.progress_bar) as progress_bar:
             for document_batch in batched_documents:
@@ -416,11 +470,17 @@ def update_document_meta(self, id: str, meta: Dict[str, str]):
         """
         self.weaviate_client.data_object.update(meta, class_name=self.index, uuid=id)
 
+    def get_embedding_count(self, filters: Optional[Dict[str, List[str]]] = None, index: Optional[str] = None) -> int:
+        """
+        Return the number of embeddings in the document store, which is the same as the number of documents since every document has a default embedding
+        """
+        return self.get_document_count(filters=filters, index=index)
+
     def get_document_count(self, filters: Optional[Dict[str, List[str]]] = None, index: Optional[str] = None) -> int:
         """
         Return the number of documents in the document store.
         """
-        index = index or self.index
+        index = self._sanitize_index_name(index) or self.index
         doc_count = 0
         if filters:
             filter_dict = self._build_filter_clause(filters=filters)
@@ -456,7 +516,7 @@ def get_all_documents(
         :param return_embedding: Whether to return the document embeddings.
         :param batch_size: When working with large number of documents, batching can help reduce memory footprint.
         """
-        index = index or self.index
+        index = self._sanitize_index_name(index) or self.index
         result = self.get_all_documents_generator(
             index=index, filters=filters, return_embedding=return_embedding, batch_size=batch_size
         )
@@ -473,7 +533,7 @@ def _get_all_documents_in_index(
         """
         Return all documents in a specific index in the document store
         """
-        index = index or self.index
+        index = self._sanitize_index_name(index) or self.index
 
         # Build the properties to retrieve from Weaviate
         properties = self._get_current_properties(index)
@@ -515,8 +575,7 @@ def get_all_documents_generator(
         :param batch_size: When working with large number of documents, batching can help reduce memory footprint.
         """
 
-        if index is None:
-            index = self.index
+        index = self._sanitize_index_name(index) or self.index
 
         if return_embedding is None:
             return_embedding = self.return_embedding
@@ -545,7 +604,7 @@ def query(
                             https://www.semi.technology/developers/weaviate/current/graphql-references/filters.html
         :param index: The name of the index in the DocumentStore from which to retrieve documents
         """
-        index = index or self.index
+        index = self._sanitize_index_name(index) or self.index
 
         # Build the properties to retrieve from Weaviate
         properties = self._get_current_properties(index)
@@ -596,7 +655,7 @@ def query_by_embedding(self,
         """
         if return_embedding is None:
             return_embedding = self.return_embedding
-        index = index or self.index
+        index = self._sanitize_index_name(index) or self.index
 
         # Build the properties to retrieve from Weaviate
         properties = self._get_current_properties(index)
@@ -657,8 +716,7 @@ def update_embeddings(
         :param batch_size: When working with large number of documents, batching can help reduce memory footprint.
         :return: None
         """
-        if index is None:
-            index = self.index
+        index = self._sanitize_index_name(index) or self.index
 
         if not self.embedding_field:
             raise RuntimeError("Specify the arg `embedding_field` when initializing WeaviateDocumentStore()")
@@ -717,7 +775,11 @@ def delete_documents(self, index: Optional[str] = None, ids: Optional[List[str]]
             have their ID in the list).
         :return: None
         """
-        index = index or self.index
+        index = self._sanitize_index_name(index) or self.index
+
+        # create index if it doesn't exist yet
+        self._create_schema_and_index_if_not_exist(index)
+
         if not filters and not ids:
             self.weaviate_client.schema.delete_class(index)
             self._create_schema_and_index_if_not_exist(index)
@@ -727,7 +789,3 @@ def delete_documents(self, index: Optional[str] = None, ids: Optional[List[str]]
                 docs_to_delete = [doc for doc in docs_to_delete if doc.id in ids]
             for doc in docs_to_delete:
                 self.weaviate_client.data_object.delete(doc.id)
-            
-
-
-
diff --git a/haystack/utils/__init__.py b/haystack/utils/__init__.py
--- a/haystack/utils/__init__.py
+++ b/haystack/utils/__init__.py
@@ -9,6 +9,7 @@
     launch_milvus,
     launch_open_distro_es,
     launch_opensearch,
+    launch_weaviate,
     stop_opensearch,
     stop_service,
 )
diff --git a/haystack/utils/doc_store.py b/haystack/utils/doc_store.py
--- a/haystack/utils/doc_store.py
+++ b/haystack/utils/doc_store.py
@@ -50,6 +50,20 @@ def launch_opensearch(sleep=15):
         time.sleep(sleep)
 
 
+def launch_weaviate(sleep=15):
+    # Start a Weaviate server via Docker
+
+    logger.info("Starting Weaviate ...")
+    status = subprocess.run(
+        ["docker run -d -p 8080:8080 --env AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED='true' --env PERSISTENCE_DATA_PATH='/var/lib/weaviate' semitechnologies/weaviate:1.7.2"], shell=True
+    )
+    if status.returncode:
+        logger.warning("Tried to start Weaviate through Docker but this failed. "
+                       "It is likely that there is already an existing Weaviate instance running. ")
+    else:
+        time.sleep(sleep)
+
+
 def stop_opensearch():
     logger.info("Stopping OpenSearch...")
     status = subprocess.run(['docker stop opensearch'], shell=True)


Test patch:
diff --git a/test/conftest.py b/test/conftest.py
--- a/test/conftest.py
+++ b/test/conftest.py
@@ -57,13 +57,6 @@ def pytest_generate_tests(metafunc):
             break
     # for all others that don't have explicit parametrization, we add the ones from the CLI arg
     if 'document_store' in metafunc.fixturenames and not found_mark_parametrize_document_store:
-        # TODO: Remove the following if-condition once weaviate is fully compliant
-        # Background: Currently, weaviate is not fully compliant (e.g. "_" in "meta_field", problems with uuids ...)
-        # Therefore, we have separate tests in test_weaviate.py and we don't want to parametrize our generic
-        # tests (e.g. in test_document_store.py) with the weaviate fixture. However, we still need the weaviate option
-        # in the CLI arg as we want to skip test_weaviate.py if weaviate is not selected from CLI
-        if "weaviate" in selected_doc_stores:
-            selected_doc_stores.remove("weaviate")
         metafunc.parametrize("document_store", selected_doc_stores, indirect=True)
 
 
@@ -172,7 +165,7 @@ def weaviate_fixture():
             shell=True
         )
         status = subprocess.run(
-            ['docker run -d --name haystack_test_weaviate -p 8080:8080 semitechnologies/weaviate:1.4.0'],
+            ['docker run -d --name haystack_test_weaviate -p 8080:8080 semitechnologies/weaviate:1.7.2'],
             shell=True
         )
         if status.returncode:
@@ -447,8 +440,7 @@ def get_retriever(retriever_type, document_store):
     return retriever
 
 
-@pytest.fixture(params=["elasticsearch", "faiss", "memory", "milvus"])
-# @pytest.fixture(params=["memory"])
+@pytest.fixture(params=["elasticsearch", "faiss", "memory", "milvus", "weaviate"])
 def document_store_with_docs(request, test_docs_xs):
     document_store = get_document_store(request.param)
     document_store.write_documents(test_docs_xs)
@@ -516,7 +508,7 @@ def get_document_store(document_store_type, embedding_dim=768, embedding_field="
     elif document_store_type == "weaviate":
         document_store = WeaviateDocumentStore(
             weaviate_url="http://localhost:8080",
-            index=index.replace('_','').title(),
+            index=index,
             similarity=similarity
         )
         document_store.weaviate_client.schema.delete_all()
diff --git a/test/test_document_store.py b/test/test_document_store.py
--- a/test/test_document_store.py
+++ b/test/test_document_store.py
@@ -4,6 +4,8 @@
 from elasticsearch import Elasticsearch
 
 from conftest import get_document_store
+from haystack.document_stores import WeaviateDocumentStore
+from haystack.errors import DuplicateDocumentError
 from haystack.schema import Document, Label, Answer, Span
 from haystack.document_stores.elasticsearch import ElasticsearchDocumentStore
 from haystack.document_stores.faiss import FAISSDocumentStore
@@ -49,6 +51,7 @@ def test_write_with_duplicate_doc_ids(document_store):
         document_store.write_documents(documents, duplicate_documents="fail")
 
 
+@pytest.mark.parametrize("document_store", ["elasticsearch", "faiss", "memory", "milvus", "weaviate"], indirect=True)
 def test_write_with_duplicate_doc_ids_custom_index(document_store):
     documents = [
         Document(
@@ -62,9 +65,24 @@ def test_write_with_duplicate_doc_ids_custom_index(document_store):
     ]
     document_store.delete_documents(index="haystack_custom_test")
     document_store.write_documents(documents, index="haystack_custom_test", duplicate_documents="skip")
-    with pytest.raises(Exception):
+    with pytest.raises(DuplicateDocumentError):
         document_store.write_documents(documents, index="haystack_custom_test", duplicate_documents="fail")
 
+    # Weaviate manipulates document objects in-place when writing them to an index.
+    # It generates a uuid based on the provided id and the index name where the document is added to.
+    # We need to get rid of these generated uuids for this test and therefore reset the document objects.
+    # As a result, the documents will receive a fresh uuid based on their id_hash_keys and a different index name.
+    if isinstance(document_store, WeaviateDocumentStore):
+        documents = [
+            Document(
+                content="Doc1",
+                id_hash_keys=["key1"]
+            ),
+            Document(
+                content="Doc2",
+                id_hash_keys=["key1"]
+            )
+        ]
     # writing to the default, empty index should still work
     document_store.write_documents(documents, duplicate_documents="fail")
 
@@ -220,13 +238,13 @@ def test_write_document_index(document_store):
         {"content": "text1", "id": "1"},
         {"content": "text2", "id": "2"},
     ]
-    document_store.write_documents([documents[0]], index="haystack_test_1")
-    assert len(document_store.get_all_documents(index="haystack_test_1")) == 1
+    document_store.write_documents([documents[0]], index="haystack_test_one")
+    assert len(document_store.get_all_documents(index="haystack_test_one")) == 1
 
-    document_store.write_documents([documents[1]], index="haystack_test_2")
-    assert len(document_store.get_all_documents(index="haystack_test_2")) == 1
+    document_store.write_documents([documents[1]], index="haystack_test_two")
+    assert len(document_store.get_all_documents(index="haystack_test_two")) == 1
 
-    assert len(document_store.get_all_documents(index="haystack_test_1")) == 1
+    assert len(document_store.get_all_documents(index="haystack_test_one")) == 1
     assert len(document_store.get_all_documents()) == 0
 
 
@@ -237,13 +255,15 @@ def test_document_with_embeddings(document_store):
         {"content": "text3", "id": "3", "embedding": np.random.rand(768).astype(np.float32).tolist()},
         {"content": "text4", "id": "4", "embedding": np.random.rand(768).astype(np.float32)},
     ]
-    document_store.write_documents(documents, index="haystack_test_1")
-    assert len(document_store.get_all_documents(index="haystack_test_1")) == 4
+    document_store.write_documents(documents, index="haystack_test_one")
+    assert len(document_store.get_all_documents(index="haystack_test_one")) == 4
 
-    documents_without_embedding = document_store.get_all_documents(index="haystack_test_1", return_embedding=False)
-    assert documents_without_embedding[0].embedding is None
+    if not isinstance(document_store, WeaviateDocumentStore):
+        # weaviate is excluded because it would return dummy vectors instead of None
+        documents_without_embedding = document_store.get_all_documents(index="haystack_test_one", return_embedding=False)
+        assert documents_without_embedding[0].embedding is None
 
-    documents_with_embedding = document_store.get_all_documents(index="haystack_test_1", return_embedding=True)
+    documents_with_embedding = document_store.get_all_documents(index="haystack_test_one", return_embedding=True)
     assert isinstance(documents_with_embedding[0].embedding, (list, np.ndarray))
 
 
@@ -254,15 +274,15 @@ def test_update_embeddings(document_store, retriever):
         documents.append({"content": f"text_{i}", "id": str(i), "meta_field": f"value_{i}"})
     documents.append({"content": "text_0", "id": "6", "meta_field": "value_0"})
 
-    document_store.write_documents(documents, index="haystack_test_1")
-    document_store.update_embeddings(retriever, index="haystack_test_1", batch_size=3)
-    documents = document_store.get_all_documents(index="haystack_test_1", return_embedding=True)
+    document_store.write_documents(documents, index="haystack_test_one")
+    document_store.update_embeddings(retriever, index="haystack_test_one", batch_size=3)
+    documents = document_store.get_all_documents(index="haystack_test_one", return_embedding=True)
     assert len(documents) == 7
     for doc in documents:
         assert type(doc.embedding) is np.ndarray
 
     documents = document_store.get_all_documents(
-        index="haystack_test_1",
+        index="haystack_test_one",
         filters={"meta_field": ["value_0"]},
         return_embedding=True,
     )
@@ -272,53 +292,57 @@ def test_update_embeddings(document_store, retriever):
     np.testing.assert_array_almost_equal(documents[0].embedding, documents[1].embedding, decimal=4)
 
     documents = document_store.get_all_documents(
-        index="haystack_test_1",
+        index="haystack_test_one",
         filters={"meta_field": ["value_0", "value_5"]},
         return_embedding=True,
     )
+    documents_with_value_0 = [doc for doc in documents if doc.meta["meta_field"] == "value_0"]
+    documents_with_value_5 = [doc for doc in documents if doc.meta["meta_field"] == "value_5"]
     np.testing.assert_raises(
         AssertionError,
         np.testing.assert_array_equal,
-        documents[0].embedding,
-        documents[1].embedding
+        documents_with_value_0[0].embedding,
+        documents_with_value_5[0].embedding
     )
 
     doc = {"content": "text_7", "id": "7", "meta_field": "value_7",
            "embedding": retriever.embed_queries(texts=["a random string"])[0]}
-    document_store.write_documents([doc], index="haystack_test_1")
+    document_store.write_documents([doc], index="haystack_test_one")
 
     documents = []
     for i in range(8, 11):
         documents.append({"content": f"text_{i}", "id": str(i), "meta_field": f"value_{i}"})
-    document_store.write_documents(documents, index="haystack_test_1")
+    document_store.write_documents(documents, index="haystack_test_one")
 
-    doc_before_update = document_store.get_all_documents(index="haystack_test_1", filters={"meta_field": ["value_7"]})[0]
+    doc_before_update = document_store.get_all_documents(index="haystack_test_one", filters={"meta_field": ["value_7"]})[0]
     embedding_before_update = doc_before_update.embedding
 
     # test updating only documents without embeddings
-    document_store.update_embeddings(retriever, index="haystack_test_1", batch_size=3, update_existing_embeddings=False)
-    doc_after_update = document_store.get_all_documents(index="haystack_test_1", filters={"meta_field": ["value_7"]})[0]
-    embedding_after_update = doc_after_update.embedding
-    np.testing.assert_array_equal(embedding_before_update, embedding_after_update)
+    if not isinstance(document_store, WeaviateDocumentStore):
+        # All the documents in Weaviate store have an embedding by default. "update_existing_embeddings=False" is not allowed
+        document_store.update_embeddings(retriever, index="haystack_test_one", batch_size=3, update_existing_embeddings=False)
+        doc_after_update = document_store.get_all_documents(index="haystack_test_one", filters={"meta_field": ["value_7"]})[0]
+        embedding_after_update = doc_after_update.embedding
+        np.testing.assert_array_equal(embedding_before_update, embedding_after_update)
 
     # test updating with filters
     if isinstance(document_store, FAISSDocumentStore):
         with pytest.raises(Exception):
             document_store.update_embeddings(
-                retriever, index="haystack_test_1", update_existing_embeddings=True, filters={"meta_field": ["value"]}
+                retriever, index="haystack_test_one", update_existing_embeddings=True, filters={"meta_field": ["value"]}
             )
     else:
         document_store.update_embeddings(
-            retriever, index="haystack_test_1", batch_size=3, filters={"meta_field": ["value_0", "value_1"]}
+            retriever, index="haystack_test_one", batch_size=3, filters={"meta_field": ["value_0", "value_1"]}
         )
-        doc_after_update = document_store.get_all_documents(index="haystack_test_1", filters={"meta_field": ["value_7"]})[0]
+        doc_after_update = document_store.get_all_documents(index="haystack_test_one", filters={"meta_field": ["value_7"]})[0]
         embedding_after_update = doc_after_update.embedding
         np.testing.assert_array_equal(embedding_before_update, embedding_after_update)
 
     # test update all embeddings
-    document_store.update_embeddings(retriever, index="haystack_test_1", batch_size=3, update_existing_embeddings=True)
-    assert document_store.get_embedding_count(index="haystack_test_1") == 11
-    doc_after_update = document_store.get_all_documents(index="haystack_test_1", filters={"meta_field": ["value_7"]})[0]
+    document_store.update_embeddings(retriever, index="haystack_test_one", batch_size=3, update_existing_embeddings=True)
+    assert document_store.get_embedding_count(index="haystack_test_one") == 11
+    doc_after_update = document_store.get_all_documents(index="haystack_test_one", filters={"meta_field": ["value_7"]})[0]
     embedding_after_update = doc_after_update.embedding
     np.testing.assert_raises(AssertionError, np.testing.assert_array_equal, embedding_before_update, embedding_after_update)
 
@@ -326,9 +350,12 @@ def test_update_embeddings(document_store, retriever):
     documents = []
     for i in range(12, 15):
         documents.append({"content": f"text_{i}", "id": str(i), "meta_field": f"value_{i}"})
-    document_store.write_documents(documents, index="haystack_test_1")
-    document_store.update_embeddings(retriever, index="haystack_test_1", batch_size=3, update_existing_embeddings=False)
-    assert document_store.get_embedding_count(index="haystack_test_1") == 14
+    document_store.write_documents(documents, index="haystack_test_one")
+
+    if not isinstance(document_store, WeaviateDocumentStore):
+        # All the documents in Weaviate store have an embedding by default. "update_existing_embeddings=False" is not allowed
+        document_store.update_embeddings(retriever, index="haystack_test_one", batch_size=3, update_existing_embeddings=False)
+        assert document_store.get_embedding_count(index="haystack_test_one") == 14
 
 
 @pytest.mark.parametrize("retriever", ["table_text_retriever"], indirect=True)
@@ -354,16 +381,16 @@ def test_update_embeddings_table_text_retriever(document_store, retriever):
                       "meta_field": "value_table_0",
                       "content_type": "table"})
 
-    document_store.write_documents(documents, index="haystack_test_1")
-    document_store.update_embeddings(retriever, index="haystack_test_1", batch_size=3)
-    documents = document_store.get_all_documents(index="haystack_test_1", return_embedding=True)
+    document_store.write_documents(documents, index="haystack_test_one")
+    document_store.update_embeddings(retriever, index="haystack_test_one", batch_size=3)
+    documents = document_store.get_all_documents(index="haystack_test_one", return_embedding=True)
     assert len(documents) == 8
     for doc in documents:
         assert type(doc.embedding) is np.ndarray
 
     # Check if Documents with same content (text) get same embedding
     documents = document_store.get_all_documents(
-        index="haystack_test_1",
+        index="haystack_test_one",
         filters={"meta_field": ["value_text_0"]},
         return_embedding=True,
     )
@@ -374,7 +401,7 @@ def test_update_embeddings_table_text_retriever(document_store, retriever):
 
     # Check if Documents with same content (table) get same embedding
     documents = document_store.get_all_documents(
-        index="haystack_test_1",
+        index="haystack_test_one",
         filters={"meta_field": ["value_table_0"]},
         return_embedding=True,
     )
@@ -385,7 +412,7 @@ def test_update_embeddings_table_text_retriever(document_store, retriever):
 
     # Check if Documents wih different content (text) get different embedding
     documents = document_store.get_all_documents(
-        index="haystack_test_1",
+        index="haystack_test_one",
         filters={"meta_field": ["value_text_1", "value_text_2"]},
         return_embedding=True,
     )
@@ -398,7 +425,7 @@ def test_update_embeddings_table_text_retriever(document_store, retriever):
 
     # Check if Documents with different content (table) get different embeddings
     documents = document_store.get_all_documents(
-        index="haystack_test_1",
+        index="haystack_test_one",
         filters={"meta_field": ["value_table_1", "value_table_2"]},
         return_embedding=True,
     )
@@ -411,7 +438,7 @@ def test_update_embeddings_table_text_retriever(document_store, retriever):
 
     # Check if Documents with different content (table + text) get different embeddings
     documents = document_store.get_all_documents(
-        index="haystack_test_1",
+        index="haystack_test_one",
         filters={"meta_field": ["value_text_1", "value_table_1"]},
         return_embedding=True,
     )
@@ -438,17 +465,25 @@ def test_delete_documents(document_store_with_docs):
     documents = document_store_with_docs.get_all_documents()
     assert len(documents) == 0
 
-    
-def test_delete_documents_by_id(document_store_with_docs):
-    doc_ids = [doc.id for doc in document_store_with_docs.get_all_documents()]
-    assert len(doc_ids) == 3
-    docs_to_delete = doc_ids[0:2]
-
-    document_store_with_docs.delete_documents(ids=docs_to_delete)
 
+def test_delete_documents_with_filters(document_store_with_docs):
+    document_store_with_docs.delete_documents(filters={"meta_field": ["test1", "test2"]})
     documents = document_store_with_docs.get_all_documents()
     assert len(documents) == 1
-    assert documents[0].id == doc_ids[2]
+    assert documents[0].meta["meta_field"] == "test3"
+
+
+def test_delete_documents_by_id(document_store_with_docs):
+    docs_to_delete = document_store_with_docs.get_all_documents(filters={"meta_field": ["test1", "test2"]})
+    docs_not_to_delete = document_store_with_docs.get_all_documents(filters={"meta_field": ["test3"]})
+
+    document_store_with_docs.delete_documents(ids=[doc.id for doc in docs_to_delete])
+    all_docs_left = document_store_with_docs.get_all_documents()
+    assert len(all_docs_left) == 1
+    assert all_docs_left[0].meta["meta_field"] == "test3"
+
+    all_ids_left = [doc.id for doc in all_docs_left]
+    assert all(doc.id in all_ids_left for doc in docs_not_to_delete)
 
 
 def test_delete_documents_by_id_with_filters(document_store_with_docs):
@@ -464,14 +499,9 @@ def test_delete_documents_by_id_with_filters(document_store_with_docs):
     all_ids_left = [doc.id for doc in all_docs_left]
     assert all(doc.id in all_ids_left for doc in docs_not_to_delete)
 
-    
-def test_delete_documents_with_filters(document_store_with_docs):
-    document_store_with_docs.delete_documents(filters={"meta_field": ["test1", "test2"]})
-    documents = document_store_with_docs.get_all_documents()
-    assert len(documents) == 1
-    assert documents[0].meta["meta_field"] == "test3"
-
 
+# exclude weaviate because it does not support storing labels
+@pytest.mark.parametrize("document_store", ["elasticsearch", "faiss", "memory", "milvus"], indirect=True)
 def test_labels(document_store):
     label = Label(
         query="question1",
@@ -556,6 +586,8 @@ def test_labels(document_store):
     assert len(labels) == 0
 
 
+# exclude weaviate because it does not support storing labels
+@pytest.mark.parametrize("document_store", ["elasticsearch", "faiss", "memory", "milvus"], indirect=True)
 def test_multilabel(document_store):
     labels =[
         Label(
@@ -666,8 +698,9 @@ def test_multilabel(document_store):
     assert len(docs) == 0
 
 
+# exclude weaviate because it does not support storing labels
+@pytest.mark.parametrize("document_store", ["elasticsearch", "faiss", "memory", "milvus"], indirect=True)
 def test_multilabel_no_answer(document_store):
-
     labels = [
         Label(
             query="question",
diff --git a/test/test_eval.py b/test/test_eval.py
--- a/test/test_eval.py
+++ b/test/test_eval.py
@@ -4,6 +4,8 @@
 from haystack.nodes.evaluator import EvalAnswers, EvalDocuments
 from haystack.pipelines.base import Pipeline
 
+
+@pytest.mark.parametrize("document_store", ["elasticsearch", "faiss", "memory", "milvus"], indirect=True)
 @pytest.mark.parametrize("batch_size", [None, 20])
 def test_add_eval_data(document_store, batch_size):
     # add eval data (SQUAD format)
@@ -47,6 +49,7 @@ def test_add_eval_data(document_store, batch_size):
     assert doc.content[start:end] == "France"
 
 
+@pytest.mark.parametrize("document_store", ["elasticsearch", "faiss", "memory", "milvus"], indirect=True)
 @pytest.mark.parametrize("reader", ["farm"], indirect=True)
 def test_eval_reader(reader, document_store: BaseDocumentStore):
     # add eval data (SQUAD format)
@@ -136,6 +139,7 @@ def test_eval_pipeline(document_store: BaseDocumentStore, reader, retriever):
     assert eval_reader.top_k_em == eval_reader_vanila.top_k_em
 
 
+@pytest.mark.parametrize("document_store", ["elasticsearch", "faiss", "memory", "milvus"], indirect=True)
 def test_eval_data_split_word(document_store):
     # splitting by word
     preprocessor = PreProcessor(
@@ -160,6 +164,7 @@ def test_eval_data_split_word(document_store):
     assert len(set(labels[0].document_ids)) == 2
 
 
+@pytest.mark.parametrize("document_store", ["elasticsearch", "faiss", "memory", "milvus"], indirect=True)
 def test_eval_data_split_passage(document_store):
     # splitting by passage
     preprocessor = PreProcessor(
diff --git a/test/test_retriever.py b/test/test_retriever.py
--- a/test/test_retriever.py
+++ b/test/test_retriever.py
@@ -4,6 +4,8 @@
 import pandas as pd
 import pytest
 from elasticsearch import Elasticsearch
+
+from haystack.document_stores import WeaviateDocumentStore
 from haystack.schema import Document
 from haystack.document_stores.elasticsearch import ElasticsearchDocumentStore
 from haystack.document_stores.faiss import FAISSDocumentStore
@@ -13,32 +15,35 @@
 from transformers import DPRContextEncoderTokenizerFast, DPRQuestionEncoderTokenizerFast
 
 
-DOCS = [
-    Document(
-        content="""Aaron Aaron ( or ; ""Ahärôn"") is a prophet, high priest, and the brother of Moses in the Abrahamic religions. Knowledge of Aaron, along with his brother Moses, comes exclusively from religious texts, such as the Bible and Quran. The Hebrew Bible relates that, unlike Moses, who grew up in the Egyptian royal court, Aaron and his elder sister Miriam remained with their kinsmen in the eastern border-land of Egypt (Goshen). When Moses first confronted the Egyptian king about the Israelites, Aaron served as his brother's spokesman (""prophet"") to the Pharaoh. Part of the Law (Torah) that Moses received from""",
-        meta={"name": "0"},
-        id="1",
-    ),
-    Document(
-        content="""Democratic Republic of the Congo to the south. Angola's capital, Luanda, lies on the Atlantic coast in the northwest of the country. Angola, although located in a tropical zone, has a climate that is not characterized for this region, due to the confluence of three factors: As a result, Angola's climate is characterized by two seasons: rainfall from October to April and drought, known as ""Cacimbo"", from May to August, drier, as the name implies, and with lower temperatures. On the other hand, while the coastline has high rainfall rates, decreasing from North to South and from to , with""",
-        id="2",
-    ),
-    Document(
-        content="""Schopenhauer, describing him as an ultimately shallow thinker: ""Schopenhauer has quite a crude mind ... where real depth starts, his comes to an end."" His friend Bertrand Russell had a low opinion on the philosopher, and attacked him in his famous ""History of Western Philosophy"" for hypocritically praising asceticism yet not acting upon it. On the opposite isle of Russell on the foundations of mathematics, the Dutch mathematician L. E. J. Brouwer incorporated the ideas of Kant and Schopenhauer in intuitionism, where mathematics is considered a purely mental activity, instead of an analytic activity wherein objective properties of reality are""",
-        meta={"name": "1"},
-        id="3",
-    ),
-    Document(
-        content="""The Dothraki vocabulary was created by David J. Peterson well in advance of the adaptation. HBO hired the Language Creatio""",
-        meta={"name": "2"},
-        id="4",
-    ),
-    Document(
-        content="""The title of the episode refers to the Great Sept of Baelor, the main religious building in King's Landing, where the episode's pivotal scene takes place. In the world created by George R. R. Martin""",
-        meta={},
-        id="5",
-    ),
-]
+@pytest.fixture()
+def docs():
+    documents = [
+        Document(
+            content="""Aaron Aaron ( or ; ""Ahärôn"") is a prophet, high priest, and the brother of Moses in the Abrahamic religions. Knowledge of Aaron, along with his brother Moses, comes exclusively from religious texts, such as the Bible and Quran. The Hebrew Bible relates that, unlike Moses, who grew up in the Egyptian royal court, Aaron and his elder sister Miriam remained with their kinsmen in the eastern border-land of Egypt (Goshen). When Moses first confronted the Egyptian king about the Israelites, Aaron served as his brother's spokesman (""prophet"") to the Pharaoh. Part of the Law (Torah) that Moses received from""",
+            meta={"name": "0"},
+            id="1",
+        ),
+        Document(
+            content="""Democratic Republic of the Congo to the south. Angola's capital, Luanda, lies on the Atlantic coast in the northwest of the country. Angola, although located in a tropical zone, has a climate that is not characterized for this region, due to the confluence of three factors: As a result, Angola's climate is characterized by two seasons: rainfall from October to April and drought, known as ""Cacimbo"", from May to August, drier, as the name implies, and with lower temperatures. On the other hand, while the coastline has high rainfall rates, decreasing from North to South and from to , with""",
+            id="2",
+        ),
+        Document(
+            content="""Schopenhauer, describing him as an ultimately shallow thinker: ""Schopenhauer has quite a crude mind ... where real depth starts, his comes to an end."" His friend Bertrand Russell had a low opinion on the philosopher, and attacked him in his famous ""History of Western Philosophy"" for hypocritically praising asceticism yet not acting upon it. On the opposite isle of Russell on the foundations of mathematics, the Dutch mathematician L. E. J. Brouwer incorporated the ideas of Kant and Schopenhauer in intuitionism, where mathematics is considered a purely mental activity, instead of an analytic activity wherein objective properties of reality are""",
+            meta={"name": "1"},
+            id="3",
+        ),
+        Document(
+            content="""The Dothraki vocabulary was created by David J. Peterson well in advance of the adaptation. HBO hired the Language Creatio""",
+            meta={"name": "2"},
+            id="4",
+        ),
+        Document(
+            content="""The title of the episode refers to the Great Sept of Baelor, the main religious building in King's Landing, where the episode's pivotal scene takes place. In the world created by George R. R. Martin""",
+            meta={},
+            id="5",
+        ),
+    ]
+    return documents
 
 #TODO check if we this works with only "memory" arg
 @pytest.mark.parametrize(
@@ -142,10 +147,10 @@ def test_elasticsearch_custom_query():
 
 @pytest.mark.slow
 @pytest.mark.parametrize("retriever", ["dpr"], indirect=True)
-def test_dpr_embedding(document_store, retriever):
+def test_dpr_embedding(document_store, retriever, docs):
 
     document_store.return_embedding = True
-    document_store.write_documents(DOCS)
+    document_store.write_documents(docs)
     document_store.update_embeddings(retriever=retriever)
     time.sleep(1)
 
@@ -165,10 +170,19 @@ def test_dpr_embedding(document_store, retriever):
 @pytest.mark.slow
 @pytest.mark.parametrize("retriever", ["retribert"], indirect=True)
 @pytest.mark.vector_dim(128)
-def test_retribert_embedding(document_store, retriever):
-
+def test_retribert_embedding(document_store, retriever, docs):
+    if isinstance(document_store, WeaviateDocumentStore):
+        # Weaviate sets the embedding dimension to 768 as soon as it is initialized.
+        # We need 128 here and therefore initialize a new WeaviateDocumentStore.
+        document_store = WeaviateDocumentStore(
+            weaviate_url="http://localhost:8080",
+            index="haystack_test",
+            embedding_dim=128
+        )
+        document_store.weaviate_client.schema.delete_all()
+        document_store._create_schema_and_index_if_not_exist()
     document_store.return_embedding = True
-    document_store.write_documents(DOCS)
+    document_store.write_documents(docs)
     document_store.update_embeddings(retriever=retriever)
     time.sleep(1)
 
@@ -184,10 +198,10 @@ def test_retribert_embedding(document_store, retriever):
 @pytest.mark.parametrize("retriever", ["table_text_retriever"], indirect=True)
 @pytest.mark.parametrize("document_store", ["elasticsearch"], indirect=True)
 @pytest.mark.vector_dim(512)
-def test_table_text_retriever_embedding(document_store, retriever):
+def test_table_text_retriever_embedding(document_store, retriever, docs):
 
     document_store.return_embedding = True
-    document_store.write_documents(DOCS)
+    document_store.write_documents(docs)
     table_data = {
         "Mountain": ["Mount Everest", "K2", "Kangchenjunga", "Lhotse", "Makalu"],
         "Height": ["8848m", "8,611 m", "8 586m", "8 516 m", "8,485m"]
diff --git a/test/test_weaviate.py b/test/test_weaviate.py
--- a/test/test_weaviate.py
+++ b/test/test_weaviate.py
@@ -6,11 +6,13 @@
 
 embedding_dim = 768
 
+
 def get_uuid():
     return str(uuid.uuid4())
 
+
 DOCUMENTS = [
-    {"content": "text1", "id":get_uuid(), "key": "a", "embedding": np.random.rand(embedding_dim).astype(np.float32)},
+    {"content": "text1", "id":"not a correct uuid", "key": "a"},
     {"content": "text2", "id":get_uuid(), "key": "b", "embedding": np.random.rand(embedding_dim).astype(np.float32)},
     {"content": "text3", "id":get_uuid(), "key": "b", "embedding": np.random.rand(embedding_dim).astype(np.float32)},
     {"content": "text4", "id":get_uuid(), "key": "b", "embedding": np.random.rand(embedding_dim).astype(np.float32)},
@@ -26,6 +28,7 @@ def get_uuid():
         Document(content="My name is Christelle and I live in Paris", id=get_uuid(), meta={"metafield": "test3", "name": "filename3"}, embedding=np.random.rand(embedding_dim).astype(np.float32))
     ]
 
+
 @pytest.fixture(params=["weaviate"])
 def document_store_with_docs(request):
     document_store = get_document_store(request.param)
@@ -33,56 +36,13 @@ def document_store_with_docs(request):
     yield document_store
     document_store.delete_documents()
 
+
 @pytest.fixture(params=["weaviate"])
 def document_store(request):
     document_store = get_document_store(request.param)
     yield document_store
     document_store.delete_documents()
 
-@pytest.mark.weaviate
-@pytest.mark.parametrize("document_store_with_docs", ["weaviate"], indirect=True)
-def test_get_all_documents_without_filters(document_store_with_docs):
-    documents = document_store_with_docs.get_all_documents()
-    assert all(isinstance(d, Document) for d in documents)
-    assert len(documents) == 3
-    assert {d.meta["name"] for d in documents} == {"filename1", "filename2", "filename3"}
-    assert {d.meta["metafield"] for d in documents} == {"test1", "test2", "test3"}
-
-@pytest.mark.weaviate
-def test_get_all_documents_with_correct_filters(document_store_with_docs):
-    documents = document_store_with_docs.get_all_documents(filters={"metafield": ["test2"]})
-    assert len(documents) == 1
-    assert documents[0].meta["name"] == "filename2"
-
-    documents = document_store_with_docs.get_all_documents(filters={"metafield": ["test1", "test3"]})
-    assert len(documents) == 2
-    assert {d.meta["name"] for d in documents} == {"filename1", "filename3"}
-    assert {d.meta["metafield"] for d in documents} == {"test1", "test3"}
-
-@pytest.mark.weaviate
-def test_get_all_documents_with_incorrect_filter_name(document_store_with_docs):
-    documents = document_store_with_docs.get_all_documents(filters={"incorrectmetafield": ["test2"]})
-    assert len(documents) == 0
-
-@pytest.mark.weaviate
-def test_get_all_documents_with_incorrect_filter_value(document_store_with_docs):
-    documents = document_store_with_docs.get_all_documents(filters={"metafield": ["incorrect_value"]})
-    assert len(documents) == 0
-
-@pytest.mark.weaviate
-def test_get_documents_by_id(document_store_with_docs):
-    documents = document_store_with_docs.get_all_documents()
-    doc = document_store_with_docs.get_document_by_id(documents[0].id)
-    assert doc.id == documents[0].id
-    assert doc.content == documents[0].content
-
-@pytest.mark.weaviate
-@pytest.mark.parametrize("document_store", ["weaviate"], indirect=True)
-def test_get_document_count(document_store):
-    document_store.write_documents(DOCUMENTS)
-    assert document_store.get_document_count() == 5
-    assert document_store.get_document_count(filters={"key": ["a"]}) == 1
-    assert document_store.get_document_count(filters={"key": ["b"]}) == 4
 
 @pytest.mark.weaviate
 @pytest.mark.parametrize("document_store", ["weaviate"], indirect=True)
@@ -98,189 +58,6 @@ def test_weaviate_write_docs(document_store, batch_size):
     documents_indexed = document_store.get_all_documents(batch_size=batch_size)
     assert len(documents_indexed) == len(DOCUMENTS)
 
-@pytest.mark.weaviate
-@pytest.mark.parametrize("document_store", ["weaviate"], indirect=True)
-def test_get_all_document_filter_duplicate_value(document_store):
-    documents = [
-        Document(
-            content="Doc1",
-            meta={"fone": "f0"},
-            id = get_uuid(),
-            embedding= np.random.rand(embedding_dim).astype(np.float32)
-        ),
-        Document(
-            content="Doc1",
-            meta={"fone": "f1", "metaid": "0"},
-            id = get_uuid(),
-            embedding = np.random.rand(embedding_dim).astype(np.float32)
-        ),
-        Document(
-            content="Doc2",
-            meta={"fthree": "f0"},
-            id = get_uuid(),
-            embedding=np.random.rand(embedding_dim).astype(np.float32)
-        )
-    ]
-    document_store.write_documents(documents)
-    documents = document_store.get_all_documents(filters={"fone": ["f1"]})
-    assert documents[0].content == "Doc1"
-    assert len(documents) == 1
-    assert {d.meta["metaid"] for d in documents} == {"0"}
-
-@pytest.mark.weaviate
-@pytest.mark.parametrize("document_store", ["weaviate"], indirect=True)
-def test_get_all_documents_generator(document_store):
-    document_store.write_documents(DOCUMENTS)
-    assert len(list(document_store.get_all_documents_generator(batch_size=2))) == 5
-
-@pytest.mark.weaviate
-@pytest.mark.parametrize("document_store", ["weaviate"], indirect=True)
-def test_write_with_duplicate_doc_ids(document_store):
-    id = get_uuid()
-    documents = [
-        Document(
-            content="Doc1",
-            id=id,
-            embedding=np.random.rand(embedding_dim).astype(np.float32)
-        ),
-        Document(
-            content="Doc2",
-            id=id,
-            embedding=np.random.rand(embedding_dim).astype(np.float32)
-        )
-    ]
-    document_store.write_documents(documents, duplicate_documents="skip")
-    with pytest.raises(Exception):
-        document_store.write_documents(documents, duplicate_documents="fail")
-
-@pytest.mark.weaviate
-@pytest.mark.parametrize("document_store", ["weaviate"], indirect=True)
-@pytest.mark.parametrize("update_existing_documents", [True, False])
-def test_update_existing_documents(document_store, update_existing_documents):
-    id = uuid.uuid4()
-    original_docs = [
-        {"content": "text1_orig", "id": id, "metafieldforcount": "a", "embedding": np.random.rand(embedding_dim).astype(np.float32)},
-    ]
-
-    updated_docs = [
-        {"content": "text1_new", "id": id, "metafieldforcount": "a", "embedding": np.random.rand(embedding_dim).astype(np.float32)},
-    ]
-
-    document_store.update_existing_documents = update_existing_documents
-    document_store.write_documents(original_docs)
-    assert document_store.get_document_count() == 1
-
-    if update_existing_documents:
-        document_store.write_documents(updated_docs, duplicate_documents="overwrite")
-    else:
-        with pytest.raises(Exception):
-            document_store.write_documents(updated_docs, duplicate_documents="fail")
-
-    stored_docs = document_store.get_all_documents()
-    assert len(stored_docs) == 1
-    if update_existing_documents:
-        assert stored_docs[0].content == updated_docs[0]["content"]
-    else:
-        assert stored_docs[0].content == original_docs[0]["content"]
-
-
-@pytest.mark.weaviate
-@pytest.mark.parametrize("document_store", ["weaviate"], indirect=True)
-def test_write_document_meta(document_store):
-    uid1 = get_uuid()
-    uid2 = get_uuid()
-    uid3 = get_uuid()
-    uid4 = get_uuid()
-    documents = [
-        {"content": "dict_without_meta", "id": uid1, "embedding": np.random.rand(embedding_dim).astype(np.float32)},
-        {"content": "dict_with_meta", "metafield": "test2", "name": "filename2", "id": uid2, "embedding": np.random.rand(embedding_dim).astype(np.float32)},
-        Document(content="document_object_without_meta", id=uid3, embedding=np.random.rand(embedding_dim).astype(np.float32)),
-        Document(content="document_object_with_meta", meta={"metafield": "test4", "name": "filename3"}, id=uid4, embedding=np.random.rand(embedding_dim).astype(np.float32)),
-    ]
-    document_store.write_documents(documents)
-    documents_in_store = document_store.get_all_documents()
-    assert len(documents_in_store) == 4
-
-    assert not document_store.get_document_by_id(uid1).meta
-    assert document_store.get_document_by_id(uid2).meta["metafield"] == "test2"
-    assert not document_store.get_document_by_id(uid3).meta
-    assert document_store.get_document_by_id(uid4).meta["metafield"] == "test4"
-
-@pytest.mark.weaviate
-@pytest.mark.parametrize("document_store", ["weaviate"], indirect=True)
-def test_write_document_index(document_store):
-    documents = [
-        {"content": "text1", "id": uuid.uuid4(), "embedding": np.random.rand(embedding_dim).astype(np.float32)},
-        {"content": "text2", "id": uuid.uuid4(), "embedding": np.random.rand(embedding_dim).astype(np.float32)},
-    ]
-
-    document_store.write_documents([documents[0]], index="Haystackone")
-    assert len(document_store.get_all_documents(index="Haystackone")) == 1
-
-    document_store.write_documents([documents[1]], index="Haystacktwo")
-    assert len(document_store.get_all_documents(index="Haystacktwo")) == 1
-
-    assert len(document_store.get_all_documents(index="Haystackone")) == 1
-    assert len(document_store.get_all_documents()) == 0
-
-@pytest.mark.weaviate
-@pytest.mark.parametrize("retriever", ["dpr", "embedding"], indirect=True)
-@pytest.mark.parametrize("document_store", ["weaviate"], indirect=True)
-def test_update_embeddings(document_store, retriever):
-    documents = []
-    for i in range(6):
-        documents.append({"content": f"text_{i}", "id": str(uuid.uuid4()), "metafield": f"value_{i}", "embedding": np.random.rand(embedding_dim).astype(np.float32)})
-    documents.append({"content": "text_0", "id": str(uuid.uuid4()), "metafield": "value_0", "embedding": np.random.rand(embedding_dim).astype(np.float32)})
-
-    document_store.write_documents(documents, index="HaystackTestOne")
-    document_store.update_embeddings(retriever, index="HaystackTestOne", batch_size=3)
-    documents = document_store.get_all_documents(index="HaystackTestOne", return_embedding=True)
-    assert len(documents) == 7
-    for doc in documents:
-        assert type(doc.embedding) is np.ndarray
-
-    documents = document_store.get_all_documents(
-        index="HaystackTestOne",
-        filters={"metafield": ["value_0"]},
-        return_embedding=True,
-    )
-    assert len(documents) == 2
-    for doc in documents:
-        assert doc.meta["metafield"] == "value_0"
-    np.testing.assert_array_almost_equal(documents[0].embedding, documents[1].embedding, decimal=4)
-
-    documents = document_store.get_all_documents(
-        index="HaystackTestOne",
-        filters={"metafield": ["value_1", "value_5"]},
-        return_embedding=True,
-    )
-    np.testing.assert_raises(
-        AssertionError,
-        np.testing.assert_array_equal,
-        documents[0].embedding,
-        documents[1].embedding
-    )
-
-    doc = {"content": "text_7", "id": str(uuid.uuid4()), "metafield": "value_7",
-           "embedding": retriever.embed_queries(texts=["a random string"])[0]}
-    document_store.write_documents([doc], index="HaystackTestOne")
-
-    doc_before_update = document_store.get_all_documents(index="HaystackTestOne", filters={"metafield": ["value_7"]})[0]
-    embedding_before_update = doc_before_update.embedding
-
-    document_store.update_embeddings(
-        retriever, index="HaystackTestOne", batch_size=3, filters={"metafield": ["value_0", "value_1"]}
-    )
-    doc_after_update = document_store.get_all_documents(index="HaystackTestOne", filters={"metafield": ["value_7"]})[0]
-    embedding_after_update = doc_after_update.embedding
-    np.testing.assert_array_equal(embedding_before_update, embedding_after_update)
-
-    # test update all embeddings
-    document_store.update_embeddings(retriever, index="HaystackTestOne", batch_size=3, update_existing_embeddings=True)
-    assert document_store.get_document_count(index="HaystackTestOne") == 8
-    doc_after_update = document_store.get_all_documents(index="HaystackTestOne", filters={"metafield": ["value_7"]})[0]
-    embedding_after_update = doc_after_update.embedding
-    np.testing.assert_raises(AssertionError, np.testing.assert_array_equal, embedding_before_update, embedding_after_update)
 
 @pytest.mark.weaviate
 @pytest.mark.parametrize("document_store_with_docs", ["weaviate"], indirect=True)
@@ -311,49 +88,3 @@ def test_query(document_store_with_docs):
 
     docs = document_store_with_docs.query(filters={"content":['live']})
     assert len(docs) == 3
-
-@pytest.mark.weaviate
-@pytest.mark.parametrize("document_store_with_docs", ["weaviate"], indirect=True)
-def test_delete_documents(document_store_with_docs):
-    assert len(document_store_with_docs.get_all_documents()) == 3
-
-    document_store_with_docs.delete_documents()
-    documents = document_store_with_docs.get_all_documents()
-    assert len(documents) == 0
-
-@pytest.mark.weaviate
-@pytest.mark.parametrize("document_store_with_docs", ["weaviate"], indirect=True)
-def test_delete_documents_with_filters(document_store_with_docs):
-    assert len(document_store_with_docs.get_all_documents()) == 3
-
-    document_store_with_docs.delete_documents(filters={"metafield": ["test1", "test2"]})
-    documents = document_store_with_docs.get_all_documents()
-    assert len(documents) == 1
-    assert documents[0].meta["metafield"] == "test3"
-
-
-@pytest.mark.weaviate
-@pytest.mark.parametrize("document_store_with_docs", ["weaviate"], indirect=True)
-def test_delete_documents_by_id(document_store_with_docs):
-    assert len(document_store_with_docs.get_all_documents()) == 3
-    ids_to_delete = [doc.id for doc in document_store_with_docs.get_all_documents()[0:2]]
-
-    document_store_with_docs.delete_documents(ids=ids_to_delete)
-    documents = document_store_with_docs.get_all_documents()
-    assert len(documents) == 1
-    assert documents[0].id not in ids_to_delete
-
-
-@pytest.mark.weaviate
-@pytest.mark.parametrize("document_store_with_docs", ["weaviate"], indirect=True)
-def test_delete_documents_by_id_with_filters(document_store_with_docs):
-    docs_to_delete = document_store_with_docs.get_all_documents(filters={"metafield": ["test1", "test2"]})
-    docs_not_to_delete = document_store_with_docs.get_all_documents(filters={"metafield": ["test3"]})
-
-    document_store_with_docs.delete_documents(ids=[doc.id for doc in docs_to_delete], filters={"metafield": ["test1"]})
-
-    all_docs_left = document_store_with_docs.get_all_documents()
-    assert len(all_docs_left) == 2
-    assert all(doc.meta["metafield"] != "test1" for doc in all_docs_left)
-    all_ids_left = [doc.id for doc in all_docs_left]
-    assert all(doc.id in all_ids_left for doc in docs_not_to_delete)