Query Elasticsearch a Milvus
Elasticsearch, basato su Apache Lucene, è uno dei principali motori di ricerca open-source. Tuttavia, nelle moderne applicazioni di intelligenza artificiale deve affrontare delle sfide, tra cui gli elevati costi di aggiornamento, le scarse prestazioni in tempo reale, la gestione inefficiente degli shard, un design non cloud-native e un'eccessiva richiesta di risorse. Come database vettoriale cloud-nativo, Milvus supera questi problemi grazie alla disgiunzione tra archiviazione e calcolo, all'indicizzazione efficiente per i dati ad alta dimensionalità e alla perfetta integrazione con le infrastrutture moderne. Offre prestazioni e scalabilità superiori per i carichi di lavoro di intelligenza artificiale.
Questo articolo mira a facilitare la migrazione della vostra base di codice da Elasticsearch a Milvus, fornendo vari esempi di conversione delle query.
Panoramica
In Elasticsearch, le operazioni nel contesto della query generano punteggi di rilevanza, mentre quelle nel contesto del filtro non lo fanno. Allo stesso modo, le ricerche di Milvus producono punteggi di similarità, mentre le sue query simili a filtri non lo fanno. Quando si migra la base di codice da Elasticsearch a Milvus, il principio chiave è la conversione dei campi utilizzati nel contesto di query di Elasticsearch in campi vettoriali per consentire la generazione di punteggi di similarità.
La tabella seguente illustra alcuni modelli di query Elasticsearch e i loro corrispondenti equivalenti in Milvus.
Query Elasticsearch |
Equivalenti in Milvus |
Osservazioni |
|---|---|---|
Query full-text |
||
Ricerca full-text |
Entrambi forniscono un insieme di funzionalità simili. |
|
Query a livello di termine |
||
|
Entrambi forniscono un insieme di funzionalità identiche o simili quando queste query Elasticsearch vengono utilizzate nel contesto del filtro. |
|
|
||
Operatori di confronto come |
||
Operatori di confronto come |
||
|
||
|
||
Operatori logici come |
Entrambi forniscono un insieme di funzionalità simili quando vengono utilizzati nel contesto del filtro. |
|
Query vettoriali |
||
Ricerca |
Milvus offre funzionalità di ricerca vettoriale più avanzate. |
|
Ricerca ibrida |
Milvus supporta diverse strategie di reranking. |
|
Query full-text
In Elasticsearch, le query full-text consentono di cercare in campi di testo analizzati, come il corpo di un'e-mail. La stringa di query viene elaborata utilizzando lo stesso analizzatore applicato al campo durante l'indicizzazione.
Query di corrispondenza
In Elasticsearch, una query match restituisce i documenti che corrispondono a un testo, un numero, una data o un valore booleano. Il testo fornito viene analizzato prima della corrispondenza.
Di seguito è riportato un esempio di richiesta di ricerca Elasticsearch con una query di corrispondenza.
resp = client.search(
query={
"match": {
"message": {
"query": "this is a test"
}
}
},
)
Milvus offre la stessa capacità attraverso la funzione di ricerca full-text. È possibile convertire la query Elasticsearch di cui sopra in Milvus come segue:
res = client.search(
collection_name="my_collection",
data=['How is the weather in Jamaica?'],
anns_field="message_sparse",
output_fields=["id", "message"]
)
Nell'esempio precedente, message_sparse è un campo vettoriale rado derivato da un campo VarChar denominato message. Milvus utilizza il modello di incorporamento BM25 per convertire i valori del campo message in incorporazioni vettoriali rade e li memorizza nel campo message_sparse. Alla ricezione della richiesta di ricerca, Milvus incorpora il payload della query in testo semplice utilizzando lo stesso modello BM25 ed esegue una ricerca vettoriale rada e restituisce i campi id e message specificati nel parametro output_fields insieme ai punteggi di similarità corrispondenti.
Per utilizzare questa funzionalità, è necessario abilitare l'analizzatore sul campo message e definire una funzione per ricavare il campo message_sparse da esso. Per istruzioni dettagliate sull'abilitazione dell'analizzatore e sulla creazione della funzione derivata in Milvus, consultare la sezione Ricerca a testo completo.
Query a livello di termine
In Elasticsearch, le query a livello di termine sono utilizzate per trovare documenti basati su valori esatti in dati strutturati, come intervalli di date, indirizzi IP, prezzi o ID di prodotti. Questa sezione illustra i possibili equivalenti di alcune query a livello di termine di Elasticsearch in Milvus. Tutti gli esempi in questa sezione sono adattati per operare nel contesto del filtro per allinearsi alle capacità di Milvus.
ID
In Elasticsearch, è possibile trovare i documenti in base ai loro ID nel contesto del filtro, come segue:
resp = client.search(
query={
"bool": {
"filter": {
"ids": {
"values": [
"1",
"4",
"100"
]
}
}
}
},
)
In Milvus, è anche possibile trovare entità in base ai loro ID, come segue:
# Use the filter parameter
res = client.query(
collection_name="my_collection",
filter="id in [1, 4, 100]",
output_fields=["id", "title"]
)
# Use the ids parameter
res = client.query(
collection_name="my_collection",
ids=[1, 4, 100],
output_fields=["id", "title"]
)
L'esempio di Elasticsearch è disponibile in questa pagina. Per maggiori dettagli sulle richieste di query e get e sulle espressioni di filtro in Milvus, consultare Query e filtri.
Query con prefisso
In Elasticsearch, è possibile trovare i documenti che contengono un prefisso specifico in un campo fornito nel contesto del filtro come segue:
resp = client.search(
query={
"bool": {
"filter": {
"prefix": {
"user": {
"value": "ki"
}
}
}
}
},
)
In Milvus, è possibile trovare le entità i cui valori iniziano con il prefisso specificato come segue:
res = client.query(
collection_name="my_collection",
filter='user like "ki%"',
output_fields=["id", "user"]
)
L'esempio di Elasticsearch è disponibile in questa pagina. Per maggiori dettagli sull'operatore like in Milvus, consultare la sezione Utilizzo di LIKE per la corrispondenza dei pattern.
Interrogazione dell'intervallo
In Elasticsearch, è possibile trovare i documenti che contengono termini all'interno di un intervallo fornito, come segue:
resp = client.search(
query={
"bool": {
"filter": {
"range": {
"age": {
"gte": 10,
"lte": 20
}
}
}
}
},
)
In Milvus, è possibile trovare le entità i cui valori in un campo specifico si trovano all'interno di un intervallo fornito come segue:
res = client.query(
collection_name="my_collection",
filter='10 <= age <= 20',
output_fields=["id", "user", "age"]
)
L'esempio di Elasticsearch è disponibile in questa pagina. Per maggiori dettagli sugli operatori di confronto in Milvus, vedere Operatori di confronto.
Query a termine
In Elasticsearch, è possibile trovare i documenti che contengono un termine esatto in un campo fornito, come segue:
resp = client.search(
query={
"bool": {
"filter": {
"term": {
"status": {
"value": "retired"
}
}
}
}
},
)
In Milvus, è possibile trovare le entità i cui valori nel campo specificato sono esattamente il termine specificato come segue:
# use ==
res = client.query(
collection_name="my_collection",
filter='status=="retired"',
output_fields=["id", "user", "status"]
)
# use TEXT_MATCH
res = client.query(
collection_name="my_collection",
filter='TEXT_MATCH(status, "retired")',
output_fields=["id", "user", "status"]
)
L'esempio di Elasticsearch è disponibile in questa pagina. Per maggiori dettagli sugli operatori di confronto in Milvus, vedere Operatori di confronto.
Interrogazione dei termini
In Elasticsearch, è possibile trovare documenti che contengono uno o più termini esatti in un campo fornito, come segue:
resp = client.search(
query={
"bool": {
"filter": {
"terms": {
"degree": [
"graduate",
"post-graduate"
]
}
}
}
}
)
Milvus non ha un'equivalenza completa di questa. Tuttavia, è possibile trovare le entità i cui valori nel campo specificato sono uno dei termini specificati come segue:
# use in
res = client.query(
collection_name="my_collection",
filter='degree in ["graduate", "post-graduate"]',
output_fields=["id", "user", "degree"]
)
# use TEXT_MATCH
res = client.query(
collection_name="my_collection",
filter='TEXT_MATCH(degree, "graduate post-graduate")',
output_fields=["id", "user", "degree"]
)
L'esempio di Elasticsearch è disponibile in questa pagina. Per maggiori dettagli sugli operatori di intervallo in Milvus, consultare Operatori di intervallo.
Query con caratteri jolly
In Elasticsearch, è possibile trovare documenti che contengono termini che corrispondono a un modello jolly, come segue:
resp = client.search(
query={
"bool": {
"filter": {
"wildcard": {
"user": {
"value": "ki*y"
}
}
}
}
},
)
Milvus non supporta i caratteri jolly nelle condizioni di filtraggio. Tuttavia, è possibile utilizzare l'operatore like per ottenere un effetto simile, come segue:
res = client.query(
collection_name="my_collection",
filter='user like "ki%" AND user like "%y"',
output_fields=["id", "user"]
)
L'esempio di Elasticsearch è disponibile in questa pagina. Per maggiori dettagli sugli operatori di intervallo in Milvus, consultare Operatori di intervallo.
Interrogazione booleana
In Elasticsearch, una query booleana è un'interrogazione che corrisponde a documenti che corrispondono a combinazioni booleane di altre query.
L'esempio seguente è adattato da un esempio presente nella documentazione di Elasticsearch in questa pagina. La query restituirà gli utenti che hanno kimchy nel loro nome con un tag production.
resp = client.search(
query={
"bool": {
"filter": {
"term": {
"user": "kimchy"
}
},
"filter": {
"term": {
"tags": "production"
}
}
}
},
)
In Milvus, si può fare una cosa simile come segue:
filter =
res = client.query(
collection_name="my_collection",
filter='user like "%kimchy%" AND ARRAY_CONTAINS(tags, "production")',
output_fields=["id", "user", "age", "tags"]
)
L'esempio precedente presuppone che nell'insieme di destinazione siano presenti un campo user di tipo VarChar e un campo tags di tipo Array. La query restituirà gli utenti con kimchy nel nome con un tag production.
Query vettoriali
In Elasticsearch, le query vettoriali sono query specializzate che lavorano su campi vettoriali per eseguire in modo efficiente la ricerca semantica.
Query Knn
Elasticsearch supporta sia le query kNN approssimate che le query kNN esatte, con forza bruta. In entrambi i casi è possibile trovare i k vettori più vicini a un vettore di query, misurati da una metrica di somiglianza, come segue:
resp = client.search(
index="my-image-index",
size=3,
query={
"knn": {
"field": "image-vector",
"query_vector": [
-5,
9,
-12
],
"k": 10
}
},
)
Milvus, in quanto database vettoriale specializzato, utilizza i tipi di indice per ottimizzare le ricerche vettoriali. In genere, privilegia la ricerca approssimata del vicino (RNA) per i dati vettoriali ad alta dimensione. La ricerca kNN a forza bruta con il tipo di indice FLAT fornisce risultati precisi, ma richiede molto tempo e risorse. Al contrario, la ricerca ANN con AUTOINDEX o altri tipi di indice bilancia velocità e precisione, offrendo prestazioni significativamente più veloci ed efficienti in termini di risorse rispetto a kNN.
Un'equivalenza simile alla query vettoriale di cui sopra in Mlivus è la seguente:
res = client.search(
collection_name="my_collection",
anns_field="image-vector"
data=[[-5, 9, -12]],
limit=10
)
L'esempio Elasticsearch è disponibile a questa pagina. Per maggiori dettagli sulle ricerche ANN in Milvus, leggere Ricerca ANN di base.
Fusione di rango reciproco
Elasticsearch offre la funzione Reciprocal Rank Fusion (RRF) per combinare più set di risultati con diversi indicatori di rilevanza in un unico set di risultati classificati.
L'esempio seguente mostra la combinazione di una ricerca tradizionale basata sui termini con una ricerca vettoriale k-nearest neighbors (kNN) per migliorare la rilevanza della ricerca:
client.search(
index="my_index",
size=10,
query={
"retriever": {
"rrf": {
"retrievers": [
{
"standard": {
"query": {
"term": {
"text": "shoes"
}
}
}
},
{
"knn": {
"field": "vector",
"query_vector": [1.25, 2, 3.5], # Example vector; replace with your actual query vector
"k": 50,
"num_candidates": 100
}
}
],
"rank_window_size": 50,
"rank_constant": 20
}
}
}
)
In questo esempio, RRF combina i risultati di due retrievers:
Una ricerca standard basata sui termini per i documenti contenenti il termine
"shoes"nel campotext.Una ricerca kNN sul campo
vectorutilizzando il vettore di query fornito.
Ciascun retriever contribuisce con un massimo di 50 top match, che vengono riclassificati da RRF e i 10 risultati finali vengono restituiti.
In Milvus è possibile ottenere una ricerca ibrida simile, combinando le ricerche su più campi vettoriali, applicando una strategia di reranking e recuperando i risultati top-K dall'elenco combinato. Milvus supporta sia le strategie di reranking RRF che quelle ponderate. Per maggiori dettagli, consultare Reranking.
Di seguito viene presentata un'equivalenza non rigorosa dell'esempio Elasticsearch di cui sopra in Milvus.
search_params_dense = {
"data": [[1.25, 2, 3.5]],
"anns_field": "vector",
"param": {
"metric_type": "IP",
"params": {"nprobe": 10},
},
"limit": 100
}
req_dense = ANNSearchRequest(**search_params_dense)
search_params_sparse = {
"data": ["shoes"],
"anns_field": "text_sparse",
"param": {
"metric_type": "BM25",
}
}
req_sparse = ANNSearchRequest(**search_params_sparse)
res = client.hybrid_search(
collection_name="my_collection",
reqs=[req_dense, req_sparse],
reranker=RRFRanker(),
limit=10
)
Questo esempio dimostra una ricerca ibrida in Milvus che combina:
Ricerca vettoriale densa: Utilizzo della metrica del prodotto interno (IP) con
nprobeimpostato su 10 per la ricerca approssimata del vicino (RNA) sul campovector.Ricerca vettoriale rada: Utilizzando la metrica di similarità BM25 sul campo
text_sparse.
I risultati di queste ricerche vengono eseguiti separatamente, combinati e riclassificati utilizzando il ranker Reciprocal Rank Fusion (RRF). La ricerca ibrida restituisce le prime 10 entità dell'elenco rielaborato.
A differenza del classificatore RRF di Elasticsearch, che unisce i risultati di query standard basate sul testo e di ricerche kNN, Milvus combina i risultati di ricerche vettoriali rade e dense, fornendo una capacità di ricerca ibrida unica, ottimizzata per i dati multimodali.
Ricostruzione
In questo articolo abbiamo affrontato le conversioni di query tipiche di Elasticsearch nei loro equivalenti di Milvus, comprese le query a livello di termine, le query booleane, le query full-text e le query vettoriali. Se avete altre domande sulla conversione di altre query Elasticsearch, non esitate a contattarci.