def get_query_vectors_from_jobs(
        queries: List[BulkSearchQueryEntity], qidx_to_job: Dict[Qidx, List[VectorisedJobPointer]],
        job_to_vectors: Dict[JHash, Dict[str, List[float]]], config: Config,
        jobs: Dict[JHash, VectorisedJobs]
) -> Dict[Qidx, List[float]]:
    """
    Retrieve the vectorised content associated to each query from the set of batch vectorise jobs.
    Handles multi-modal queries, by weighting and combining queries into a single vector

    Args:
        - queries: Original search queries.
        - qidx_to_job: VectorisedJobPointer for each query
        - job_to_vectors: inference output from each VectorisedJob
        - config: standard Marqo config.

    """
    result: Dict[Qidx, List[float]] = defaultdict(list)
    for qidx, ptrs in qidx_to_job.items():

        # vectors = job_to_vectors[ptrs.job_hash][ptrs.start_idx: ptrs.end_idx]

        # qidx_to_vectors[qidx].append(vectors)
        q = queries[qidx]

        if isinstance(q.q, dict) or q.q is None:
            ordered_queries = list(q.q.items()) if isinstance(q.q, dict) else None
            weighted_vectors = []
            if ordered_queries:
                # multiple queries. We have to weight and combine them:
                vectorised_ordered_queries = [
                    (
                        get_content_vector(
                            possible_jobs=qidx_to_job[qidx],
                            job_to_vectors=job_to_vectors,
                            content=content
                        ),
                        weight,
                        content
                    ) for content, weight in ordered_queries
                ]
                # TODO how do we ensure order?
                weighted_vectors = [np.asarray(vec) * weight for vec, weight, content in vectorised_ordered_queries]

            context_tensors = q.get_context_tensor()
            if context_tensors is not None:
                weighted_vectors += [np.asarray(v.vector) * v.weight for v in context_tensors]

            for vector in weighted_vectors:
                if not q.index.model.get_dimension() == len(vector):
                    raise api_exceptions.InvalidArgError(
                        f"The dimension of the vectors returned by the model or given by the context vectors "
                        f"does not match the expected dimension. "
                        f"Expected dimension {q.index.model.get_dimension()} but got {len(vector)}"
                    )

            merged_vector = np.mean(weighted_vectors, axis=0)

            if q.index.normalize_embeddings:
                norm = np.linalg.norm(merged_vector, axis=-1, keepdims=True)
                if norm > 0:
                    merged_vector /= np.linalg.norm(merged_vector, axis=-1, keepdims=True)
            result[qidx] = list(merged_vector)
        elif isinstance(q.q, str):
            # result[qidx] = vectors[0]
            result[qidx] = get_content_vector(
                possible_jobs=qidx_to_job.get(qidx, []),
                job_to_vectors=job_to_vectors,
                content=q.q
            )
        else:
            raise ValueError(f"Unexpected query type: {type(q.q).__name__}")
    return result

    Retrieve the vectorised content associated to each query from the set of batch vectorise jobs.
    Handles multi-modal queries, by weighting and combining queries into a single vector

    Args:
        - queries: Original search queries.
        - qidx_to_job: VectorisedJobPointer for each query
        - job_to_vectors: inference output from each VectorisedJob
        - config: standard Marqo config.

    
src/marqo/tensor_search/tensor_search.py