La búsqueda por facetas te permite adjuntar información categórica a tus documentos. Una faceta es un par atributo/valor. Por ejemplo, la faceta "tamaño" puede tener los valores "pequeño", "mediano" y "grande".
Al usar facetas con la búsqueda, puedes obtener información resumida que te ayude a acotar una consulta y a desglosar los resultados en una serie de pasos.
Esto resulta útil en aplicaciones como los sitios de compras, donde se pretende ofrecer un conjunto de filtros para que los clientes puedan acotar los productos que quieren ver.
Los datos agregados de una faceta muestran cómo se distribuyen los valores de esa faceta. Por ejemplo, la faceta "tamaño" puede aparecer en muchos de los documentos de tu conjunto de resultados. Los datos agregados de esa faceta pueden mostrar que el valor "pequeño" ha aparecido 100 veces, "mediano" 300 veces y "grande" 250 veces. Cada par facet/valor representa un subconjunto de documentos en el resultado de la consulta. A cada par se le asocia una clave, llamada refinamiento. Puedes incluir acotaciones en una consulta para obtener documentos que coincidan con la cadena de consulta y que tengan los valores de facet correspondientes a una o varias acotaciones.
Cuando realices una búsqueda, puedes elegir las facetas que quieres recoger y mostrar con los resultados, o bien habilitar la detección de facetas para seleccionar automáticamente las que aparecen con más frecuencia en tus documentos.
Añadir facetas a un documento
Añade facetas a un documento antes de añadirlo a un índice. Hazlo al mismo tiempo que especificas los campos del documento:
package app
import (
"appengine"
"appengine/search"
"net/http"
)
type ComputerDoc struct {
Name search.Atom
Type search.Atom `search:",facet"`
RAMSizeGB float64 `search:",facet"`
}
func handlePut(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
index, err := search.Open("products")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
_, err = index.Put(c, "doc1", &ComputerDoc{
Name: "x86",
Type: "computer",
RAMSizeGB: 8.0,
})
// Handle err and write HTTP response.
}
Una faceta es similar a un campo de documento: tiene un nombre y toma un valor.
Los nombres de las facetas siguen las mismas reglas que los campos de los documentos: distinguen entre mayúsculas y minúsculas, y solo pueden contener caracteres ASCII. Deben empezar por una letra y pueden contener letras, números o guiones bajos. El nombre no puede tener más de 500 caracteres.
El valor de una faceta puede ser una cadena atómica (de 500 caracteres como máximo) o un número (un valor de coma flotante de doble precisión comprendido entre -2.147.483.647 y 2.147.483.647).
Puedes asignar varios valores a una faceta de un documento añadiendo una faceta con el mismo nombre y tipo varias veces, usando un valor diferente cada vez.
No hay límite en el número de valores que puede tener una faceta. Tampoco hay límite en cuanto al número de facetas que puede añadir a un documento ni al número de facetas con nombres únicos en un índice.
Ten en cuenta que cada vez que uses una faceta, puede tomar un valor atómico o numérico. Se puede asociar una faceta con el nombre "size" a un documento con el valor de cadena "small" y a otro documento con el valor numérico 8. De hecho, la misma faceta puede aparecer varias veces en el mismo documento con ambos tipos de valores. Aunque se permite, no recomendamos usar valores de átomo y de número para la misma faceta.
Aunque una faceta tiene un tipo específico cuando la añades a un documento, los resultados de búsqueda reúnen todos sus valores. Por ejemplo, los resultados de la faceta "size" pueden mostrar que hubo 100 instancias del valor "small", 150 instancias de "medium" y 135 instancias de valores numéricos en el intervalo [4, 8). No se muestran los valores numéricos exactos ni su distribución de frecuencia.
Cuando recuperas un documento mediante una consulta, no puedes acceder directamente a sus facetas y valores. Debes solicitar que se devuelva la información de las facetas con tu consulta, tal como se explica en la sección siguiente.
Usar una búsqueda por facetas para obtener información de las facetas
Puedes pedirle al backend de búsqueda que descubra las facetas que se usan con más frecuencia. Esto se llama descubrimiento automático de facetas. También puede recuperar información de facetas de forma explícita seleccionando una faceta por su nombre o por su nombre y valor. Puedes combinar los tres tipos de recuperación de facetas en una sola consulta.
Solicitar información de facetas no afectará a los documentos que devuelva tu consulta. Puede afectar al rendimiento. Realizar una búsqueda por facetas con la profundidad predeterminada de 1000 tiene el mismo efecto que definir el límite de puntuación de las opciones de ordenación en 1000.
Descubrimiento automático de facetas
La detección automática de facetas busca las facetas que aparecen con más frecuencia en el conjunto de tus documentos. Por ejemplo, supongamos que los documentos que coinciden con su consulta incluyen una faceta "color" que aparece 5 veces con el valor "rojo", 5 veces con el valor "blanco" y 5 veces con el color "azul". Esta faceta tiene un recuento total de 15. A efectos de descubrimiento, se clasificaría por encima de otra faceta "shade" que aparece en los mismos documentos coincidentes 6 veces con el valor "dark" y 7 veces con el valor "light".
Para habilitar la detección de facetas, debes definirla en la consulta:
func handleSearch(w http.ResponseWriter, r *http.Request) {
index, err := search.Open("products")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
it := index.Search(c, "name:x86", &search.SearchOptions{
Facets: {
search.AutoFacetDiscovery(0, 0),
},
})
facets, err := it.Facets()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
for _, results := range facets {
for i, facet := range result {
// The facet results are grouped by facet name.
// Print the name of each group before its values.
if i == 0 {
fmt.Fprintf(w, "Facet %s:\n", facet.Name)
}
fmt.Fprintf(w, " %v: count=%d", facet.Value, facet.Count)
}
}
}
Cuando recupera facetas mediante el descubrimiento, de forma predeterminada solo se devuelven los 10 valores más frecuentes de una faceta.
Puedes aumentar este límite hasta 100 usando el primer parámetro de AutoFacetDiscovery.
Ten en cuenta que la detección automática de facetas no está diseñada para devolver todas las facetas posibles y sus valores. Las facetas devueltas por el descubrimiento pueden variar de una ejecución a otra. Si quieres usar un conjunto fijo de facetas, usa el parámetro return_facets en tu consulta.
Los valores de cadena se devolverán individualmente. Los valores numéricos de una faceta descubierta se devuelven en un único intervalo [mín. máx.). Puedes examinar este intervalo y crear un subintervalo más pequeño para una consulta posterior.
Seleccionar facetas por nombre
Para obtener información sobre una faceta solo por su nombre, añade unFacetDiscovery con el nombre de la faceta a las opciones de búsqueda de tu consulta:
it := index.Search(c, "name:x86", &search.SearchOptions{
Facets: {
FacetDiscovery("Type"),
FacetDiscovery("RAMSizeGB"),
},
})
Cuando recuperas facetas por nombre, solo se devuelven los 10 valores más frecuentes de una faceta.
Seleccionar facetas por nombre y valor
Para obtener información solo sobre valores concretos de una faceta, añade un objeto FacetDiscovery con el nombre de la faceta y los valores que te interesen:it := index.Search(c, "name:x86", &search.SearchOptions{
Facets: {
// Fetch the "Type" facet with Values "computer" and "printer"
FacetDiscovery("Type",
search.Atom("computer"),
search.Atom("printer"),
),
// Fetch the "RAMSizeGB" facet with values in the ranges [0, 4), [4, 8), and [8, max]
FacetDiscovery("RAMSizeGB",
search.Range{Start: 0, End: 4},
search.Range{Start: 4, End: 8},
search.AtLeast(8),
),
},
})
Todos los valores de un mismo FacetDiscovery deben ser del mismo tipo: una lista de valores search.Atom o, en el caso de los números, una lista de search.Range, que son intervalos cerrados por la izquierda (inicio) y abiertos por la derecha (final). Si tu faceta tiene una combinación de valores de cadena y numéricos, añade opciones FacetDisovery independientes para cada uno.
Opciones
Puedes controlar el número mínimo de documentos que se deben evaluar para obtener información de las facetas añadiendo la opciónFacetDocumentDepth en el SearchOptions de tu consulta.
Si no se especifica, la profundidad predeterminada es 1000.
Ten en cuenta que la profundidad de las facetas suele ser mucho mayor que el límite de consultas. Los resultados de las facetas se calculan con una profundidad de al menos el número de documentos. Si has definido un límite de puntuación de las opciones de ordenación superior a la profundidad, se usará el límite de puntuación.
Recuperar resultados de facetas
Cuando usas parámetros de búsqueda por facetas en una consulta, la información de las facetas agregadas se incluye en el resultado de la consulta.
La búsqueda Iterator tiene un método Facets que devuelve la información agregada de la faceta como [][]FacetResult.
Los resultados se organizan de forma que haya una porción de resultados de faceta por cada faceta que aparezca en un documento que coincida con tu consulta. En cada resultado, se mostrará lo siguiente:
- El nombre del facet
- Un valor de la faceta de la lista de los valores más frecuentes
- Recuento aproximado de cuántas veces ha aparecido ese valor.
Ten en cuenta que la lista de valores incluirá los valores de cadena y numéricos de una faceta. Si la faceta se ha detectado automáticamente, sus valores numéricos se devuelven como un solo intervalo [mín. máx.). Si has solicitado explícitamente una faceta numérica con uno o varios intervalos en tu consulta, la lista contendrá un intervalo cerrado-abierto [inicio fin) por cada intervalo.
Es posible que la lista de valores de faceta no incluya todos los valores encontrados en los documentos, ya que las opciones de consulta determinan cuántos documentos se deben examinar y cuántos valores se deben devolver.
La información agregada de cada faceta se puede leer del iterador:
it := index.Search(...)
facets, err := it.Facets() // And check err != nil.
for _, results := range facets {
for _, facet := range results {
...
}
}
Por ejemplo, una consulta puede haber encontrado documentos que incluyeran una faceta "tamaño" con valores de cadena y valores numéricos. Los resultados de esta faceta se estructurarán de la siguiente manera:
[][]search.FacetResult{
{
{Name: "size", Value: search.Range{Start: 8, End: 10}, Count: 22},
{Name: "size", Value: search.Atom("small"), Count: 100},
{Name: "size", Value: search.Atom("medium"), Count: 300},
{Name: "size", Value: search.Atom("large"), Count: 250},
},
}
Usar facetas para acotar o filtrar una consulta
Cada FacetResult se puede usar para acotar aún más los resultados e incluir solo los documentos que tengan esos valores de faceta. Para acotar las consultas con una o varias de estas claves, pásalas como opciones de búsqueda:
it := index.Search(c, "...", &search.SearchOptions{
Refinements: []search.Facet{
facetResult1.Facet,
facetResult2.Facet,
},
})
Puedes combinar refinamientos de una o varias facetas diferentes en la misma solicitud. Todas las acotaciones que pertenecen a la misma faceta se combinan con un operador OR. Las acotaciones de diferentes facetas se combinan con un operador AND.
También es posible crear un Facet personalizado manualmente para usarlo como acotación.
Consulta la referencia para obtener más información.