Ricerca…


Osservazioni

È facile vedere i type come una tabella in un database SQL, in cui l' index è il database SQL. Tuttavia, non è un buon modo per avvicinarsi ai type .

Tutto sui tipi

In effetti, i tipi sono letteralmente solo un campo di metadati aggiunto a ogni documento da Elasticsearch: _type . Gli esempi precedenti hanno creato due tipi: my_type e my_other_type . Ciò significa che ogni documento associato ai tipi ha un campo extra definito automaticamente come "_type": "my_type" ; questo è indicizzato con il documento, rendendolo quindi un campo ricercabile o filtrabile , ma non ha alcun impatto sul documento stesso, quindi l'applicazione non deve preoccuparsi di ciò.

Tutti i tipi vivono nello stesso indice e quindi negli stessi frammenti collettivi dell'indice. Anche a livello di disco, vivono negli stessi file. L'unica separazione che crea un secondo tipo fornisce è logica. Ogni tipo, sia esso univoco o meno, deve esistere nei mapping e tutti questi mapping devono esistere nello stato del cluster. Questo consuma memoria e, se ogni tipo viene aggiornato dinamicamente, consuma le prestazioni man mano che cambiano i mapping.

Pertanto, è consigliabile definire un solo tipo, a meno che non sia effettivamente necessario un altro tipo. È comune vedere scenari in cui sono desiderabili più tipi. Ad esempio, immagina di avere un indice di auto. Potrebbe essere utile per scomporlo con più tipi:

  • BMW
  • chevy
  • honda
  • mazda
  • mercedes
  • nissan
  • Rangerover
  • toyota
  • ...

In questo modo è possibile cercare tutte le auto o limitarlo per produttore su richiesta. La differenza tra queste due ricerche è semplice come:

GET /cars/_search

e

GET /cars/bmw/_search

Ciò che non è ovvio ai nuovi utenti di Elasticsearch è che il secondo modulo è una specializzazione del primo modulo. Viene letteralmente riscritto in:

GET /cars/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "term" : {
            "_type": "bmw"
          }
        }
      ]
    }
  }
}

Filtra semplicemente qualsiasi documento che non è stato indicizzato con un campo _type cui valore era bmw . Poiché ogni documento è indicizzato con il suo tipo come il campo _type , questo serve da filtro piuttosto semplice. Se in entrambi gli esempi è stata fornita una ricerca effettiva, il filtro verrà aggiunto alla ricerca completa secondo necessità.

Pertanto, se i tipi sono identici, è molto meglio fornire un singolo tipo (ad esempio, manufacturer in questo esempio) ed ignorarlo efficacemente. Quindi, all'interno di ciascun documento, fornisci esplicitamente un campo chiamato make o nome che preferisci e filtra manualmente su di esso ogni volta che vuoi limitarlo. Questo ridurrà la dimensione dei tuoi mapping a 1/n dove n è il numero di tipi separati. Aggiunge un altro campo a ciascun documento, a vantaggio di una mappatura altrimenti semplificata.

In Elasticsearch 1.xe 2.x, tale campo deve essere definito come

PUT /cars
{
  "manufacturer": { <1>
    "properties": {
      "make": { <2>
        "type": "string",
        "index": "not_analyzed"
      }
    }
  }
}
  1. Il nome è arbitrario.
  2. Il nome è arbitrario e potrebbe corrispondere al nome del tipo, se lo si desidera anche.

In Elasticsearch 5.x, quanto sopra funzionerà ancora (è deprecato), ma il modo migliore è usare:

PUT /cars
{
  "manufacturer": { <1>
    "properties": {
      "make": { <2>
        "type": "keyword"
      }
    }
  }
}
  1. Il nome è arbitrario.
  2. Il nome è arbitrario e potrebbe corrispondere al nome del tipo, se lo si desidera anche.

I tipi dovrebbero essere usati con moderazione all'interno dei vostri indici perché gonfiano le mappature degli indici, di solito senza troppi benefici. Devi averne almeno uno, ma non c'è nulla che dice che devi averne più di uno.

Domande comuni

  • Cosa succede se ho due (o più) tipi che sono per lo più identici, ma che hanno alcuni campi univoci per tipo?

A livello di indice, non vi è alcuna differenza tra un tipo usato con pochi campi scarsamente usati e tra più tipi che condividono un gruppo di campi non sparsi con pochi non condivisi (il che significa che l'altro tipo non usa mai il campo (S)).

Detto in modo diverso: un campo scarsamente usato è scarso nell'indice indipendentemente dai tipi . La sparsità non avvantaggia, o fa davvero male, l'indice solo perché è definito in un tipo separato.

Dovresti semplicemente combinare questi tipi e aggiungere un campo di testo separato.

  • Perché i tipi separati devono definire i campi nello stesso modo?

Perché ogni campo viene definito solo una volta a livello di Lucene, indipendentemente da quanti tipi ci sono. Il fatto che i tipi esistano è una caratteristica di Elasticsearch ed è solo una separazione logica.

  • Posso definire tipi separati con lo stesso campo definito in modo diverso?

No. Se riesci a trovare un modo per farlo in ES 2.xo versioni successive, dovresti aprire una segnalazione di bug . Come notato nella domanda precedente, Lucene li vede tutti come un singolo campo, quindi non c'è modo di fare questo lavoro in modo appropriato.

ES 1.x lo ha lasciato come requisito implicito, che ha consentito agli utenti di creare condizioni in cui le mappature di un frammento in un indice in realtà differivano da un altro frammento nello stesso indice. Questa era effettivamente una condizione di gara e poteva portare a problemi imprevisti.

Eccezioni alla regola

  • I documenti padre / figlio richiedono tipi separati da utilizzare all'interno dello stesso indice.
    • Il genitore vive in un tipo.
    • Il bambino vive in un tipo separato (ma ogni bambino vive nella stessa scheggia del genitore).
  • Casi di utilizzo estremamente di nicchia in cui creare tonnellate di indici è indesiderabile e l'impatto dei campi sparsi è preferibile all'alternativa.
    • Ad esempio, il plug-in di monitoraggio Elasticsearch, Marvel (1.xe 2.x) o X-Pack Monitoring (5.x +), monitora Elasticsearch stessa per le modifiche nel cluster, i nodi, gli indici, gli indici specifici (il livello dell'indice), e anche frammenti. Potrebbe creare più di 5+ indici ogni giorno per isolare quei documenti che hanno mappature univoche o potrebbe andare contro le migliori pratiche per ridurre il carico del cluster condividendo un indice (nota: il numero di mappature definite è effettivamente lo stesso, ma il numero di indici creati è ridotto da n a 1).
    • Questo è uno scenario avanzato, ma è necessario considerare le definizioni dei campi condivise tra i tipi!

Creazione esplicita di un indice con un tipo

Esempio utilizza HTTP di base, che si traduce facilmente in cURL e altre applicazioni HTTP. Corrispondono anche alla sintassi Sense , che verrà rinominata Console in Kibana 5.0.

Nota: l'esempio inserisce <#> per attirare l'attenzione sulle parti. Quelli dovrebbero essere rimossi se lo copi!

PUT /my_index <1>
{
  "mappings": {
    "my_type": { <2>
      "properties": {
        "field1": {
          "type": "long"
        },
        "field2": {
          "type": "integer"
        },
        "object1": {
          "type": "object",
          "properties": {
            "field1" : {
              "type": "float"
            }
          }
        }
      }
    }
  },
  "my_other_type": {
    "properties": {
      "field1": {
        "type": "long" <3>
      },
      "field3": { <4>
        "type": "double"
      }
    }
  }
}
  1. Questo sta creando l' index usando l'endpoint di creazione dell'indice.
  2. Questo sta creando il type .
  3. I campi condivisi in type s all'interno dello stesso index devono condividere la stessa definizione! ES 1.x non ha applicato rigorosamente questo comportamento, ma era un requisito implicito. ES 2.xe precedenti applicano rigorosamente questo comportamento.
  4. I campi unici tra i type s sono a posto.

Gli indici (o indici) contengono tipi. I tipi sono un meccanismo utile per separare i documenti, ma richiedono di definire, dinamicamente / automaticamente o esplicitamente, una mappatura per ogni tipo che si utilizza. Se si definiscono 15 tipi in un indice, si avranno 15 mappature univoche.

Vedi le osservazioni per maggiori dettagli su questo concetto e perché potresti o non vuoi usare i tipi.

Creazione dinamica di un indice con un tipo

Esempio utilizza HTTP di base, che si traduce facilmente in cURL e altre applicazioni HTTP. Corrispondono anche alla sintassi Sense , che verrà rinominata Console in Kibana 5.0.

Nota: l'esempio inserisce <#> per attirare l'attenzione sulle parti. Quelli dovrebbero essere rimossi se lo copi!

DELETE /my_index <1>

PUT /my_index/my_type/abc123 <2>
{
  "field1" : 1234, <3>
  "field2" : 456,
  "object1" : {
    "field1" : 7.8 <4>
  }
}
  1. Nel caso esista già (a causa di un esempio precedente), eliminare l'indice.
  2. Indicizza un documento nell'indice, my_index , con il tipo, my_type e l'ID abc123 (potrebbe essere numerico, ma è sempre una stringa).
    • Per impostazione predefinita, la creazione dell'indice dinamico è abilitata semplicemente indicizzando un documento. Questo è ottimo per gli ambienti di sviluppo, ma non è necessariamente un bene per gli ambienti di produzione.
  3. Questo campo è un numero intero, quindi la prima volta che viene visto deve essere mappato. Elasticsearch assume sempre il tipo più largo per qualsiasi tipo di ingresso, quindi questo verrà mappato come un numero long anziché un integer o un short (entrambi potrebbero contenere 1234 e 456 ).
  4. Lo stesso vale per questo campo. Sarà mappato come un double invece di un float come si potrebbe desiderare.

Questo indice e tipo creati dinamicamente corrispondono alla mappatura definita nel primo esempio. Tuttavia, è fondamentale capire in che modo <3> e <4> influiscono sui mapping definiti automaticamente.

Puoi seguire questo aggiungendo un altro tipo in modo dinamico allo stesso indice:

PUT /my_index/my_other_type/abc123 <1>
{
  "field1": 91, <2>
  "field3": 4.567
}
  1. Il tipo è l'unica differenza dal documento sopra. L'ID è lo stesso e va bene! Non ha alcuna relazione con l'altro abc123 oltre a quello che si trova nello stesso indice.
  2. field1 esiste già nell'indice, quindi deve essere lo stesso tipo di campo definito negli altri tipi. L'invio di un valore che fosse una stringa o non un intero sarebbe fallito (ad es. "field1": "this is some text" o "field1": 123.0 ).

Ciò crea dinamicamente i mapping per my_other_type all'interno dello stesso indice, my_index .

Nota: è sempre più rapido definire le associazioni in anticipo anziché avere Elasticsearch eseguirlo dinamicamente al momento dell'indice.

Il risultato finale dell'indicizzazione di entrambi i documenti sarebbe simile al primo esempio, ma i tipi di campo sarebbero diversi e quindi leggermente dispendiosi:

GET /my_index/_mappings <1>
{
  "mappings": {
    "my_type": { <2>
      "properties": {
        "field1": {
          "type": "long"
        },
        "field2": {
          "type": "long" <3>
        },
        "object1": {
          "type": "object",
          "properties": {
            "field1" : {
              "type": "double" <4>
            }
          }
        }
      }
    }
  },
  "my_other_type": { <5>
    "properties": {
      "field1": {
        "type": "long"
      },
      "field3": {
        "type": "double"
      }
    }
  }
}
  1. Questo utilizza l'endpoint _mappings per ottenere i mapping dall'indice che abbiamo creato.
  2. Abbiamo creato dinamicamente my_type nel primo passaggio di questo esempio.
  3. field2 è ora un long invece di un integer perché non lo abbiamo definito in anticipo. Questo potrebbe rivelarsi uno spreco nella memoria del disco.
  4. object1.field1 ora è un double per la stessa ragione del # 3 con le stesse ramificazioni del # 3.
    • Tecnicamente, un long può essere compresso in molti casi. Tuttavia, un double non può essere compresso perché è un numero in virgola mobile.
  5. Abbiamo anche creato dinamicamente my_other_type nel secondo passaggio di questo esempio. La sua mappatura sembra essere la stessa perché stavamo già usando long e double .
    • Ricorda che field1 deve corrispondere alla definizione di my_type (e lo fa).
    • field3 è unico per questo tipo, quindi non ha tale restrizione.


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow