A pesquisa com filtros permite-lhe anexar informações categóricas aos seus documentos. Uma faceta é um par atributo/valor. Por exemplo, a faceta denominada "tamanho" pode ter os valores "pequeno", "médio" e "grande".
Ao usar facetas com a pesquisa, pode obter informações de resumo para ajudar a refinar uma consulta e analisar detalhadamente os resultados numa série de passos.
Isto é útil para aplicações como sites de compras, onde pretende oferecer um conjunto de filtros para os clientes restringirem os produtos que querem ver.
Os dados agregados de uma faceta mostram como os valores de uma faceta estão distribuídos. Por exemplo, a faceta "tamanho" pode aparecer em muitos dos documentos no seu conjunto de resultados. Os dados agregados dessa faceta podem mostrar que o valor "small" apareceu 100 vezes, "medium" 300 vezes e "large" 250 vezes. Cada par de faceta/valor representa um subconjunto de documentos no resultado da consulta. Uma chave, denominada refinamento, está associada a cada par. Pode incluir refinamentos numa consulta para obter documentos que correspondam à string de consulta e que tenham os valores de facetas correspondentes a um ou mais refinamentos.
Quando faz uma pesquisa, pode escolher os atributos a recolher e apresentar com os resultados ou pode ativar a deteção de atributos para selecionar automaticamente os atributos que aparecem com maior frequência nos seus documentos.
Adicionar facetas a um documento
Adicione facetas a um documento antes de adicionar o documento a um índice. Faça isto ao mesmo tempo que especifica os campos do 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.
}
Uma faceta é semelhante a um campo de documento; tem um nome e assume um valor.
Os nomes das facetas seguem as mesmas regras que os campos de documentos: os nomes são sensíveis a maiúsculas e minúsculas e só podem conter carateres ASCII. Têm de começar por uma letra e podem conter letras, dígitos ou um caráter de sublinhado. Um nome não pode ter mais de 500 carateres.
O valor de uma faceta pode ser uma string atómica (com um máximo de 500 carateres) ou um número (um valor de vírgula flutuante de precisão dupla entre -2 147 483 647 e 2 147 483 647).
Pode atribuir vários valores a uma faceta num documento adicionando uma faceta com o mesmo nome e tipo várias vezes, usando um valor diferente de cada vez.
Não existe limite para o número de valores que uma faceta pode ter. Também não existe limite para o número de facetas que pode adicionar a um documento nem para o número de facetas com nomes únicos num índice.
Tenha em atenção que, cada vez que usa uma faceta, esta pode assumir um valor atómico ou numérico. Uma faceta com o nome "size" pode ser anexada a um documento com o valor de string "small" e a outro documento com o valor numérico 8. Na verdade, o mesmo aspeto pode aparecer várias vezes no mesmo documento com ambos os tipos de valores. Não recomendamos a utilização de valores de átomos e números para a mesma faceta, apesar de ser permitido.
Embora um aspeto tenha um tipo específico quando o adiciona a um documento, os resultados da pesquisa reúnem todos os respetivos valores. Por exemplo, os resultados da faceta "tamanho" podem mostrar que existiram 100 instâncias do valor "pequeno", 150 instâncias de "médio" e 135 instâncias de valores numéricos no intervalo [4, 8). Os valores numéricos exatos e a respetiva distribuição de frequência não são apresentados.
Quando obtém um documento através de uma consulta, não pode aceder diretamente às respetivas facetas e valores. Tem de pedir que as informações de facetas sejam devolvidas com a sua consulta, conforme explicado na secção seguinte.
Usar uma pesquisa com filtros para obter informações de filtros
Pode pedir ao back-end de pesquisa para descobrir os atributos usados com mais frequência. Isto chama-se descoberta automática de atributos. Também pode obter informações de facetas explicitamente selecionando uma faceta por nome ou por nome e valor. Pode combinar os três tipos de obtenção de facetas numa única consulta.
Pedir informações de facetas não afeta os documentos devolvidos pela sua consulta. Pode afetar o desempenho. A realização de uma pesquisa com filtros com a profundidade predefinida de 1000 tem o mesmo efeito que definir o limite do avaliador das opções de ordenação como 1000.
Descoberta automática de facetas
A deteção automática de facetas procura as facetas que aparecem com mais frequência no total nos seus documentos. Por exemplo, suponhamos que os documentos que correspondem à sua consulta incluem uma faceta "cor" que aparece 5 vezes com o valor "vermelho", 5 vezes com o valor "branco" e 5 vezes com a cor "azul". Esta faceta tem uma contagem total de 15. Para fins de descoberta, seria classificado mais alto do que outra faceta "shade" que aparece nos mesmos documentos correspondentes 6 vezes com o valor "dark" e 7 vezes com o valor "light".
Tem de ativar a descoberta de facetas definindo-a na sua 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)
}
}
}
Quando obtém facetas por deteção, por predefinição, apenas são devolvidos os 10 valores que ocorrem com mais frequência para uma faceta.
Pode aumentar este limite até 100 usando o primeiro parâmetro para AutoFacetDiscovery
.
Tenha em atenção que a descoberta automática de facetas não se destina a devolver todas as facetas possíveis e os respetivos valores. As facetas devolvidas da descoberta podem variar de execução para execução. Se quiser um conjunto fixo de facetas, use um parâmetro return_facets
na sua consulta.
Os valores de string são devolvidos individualmente. Os valores numéricos de uma faceta descoberta são devolvidos num único intervalo [min max). Pode examinar este intervalo e criar um subintervalo mais pequeno para uma consulta posterior.
Selecionar facetas por nome
Para obter informações sobre uma faceta apenas pelo respetivo nome, adicione umFacetDiscovery
com o nome da faceta
às opções de pesquisa da sua consulta:
it := index.Search(c, "name:x86", &search.SearchOptions{
Facets: {
FacetDiscovery("Type"),
FacetDiscovery("RAMSizeGB"),
},
})
Quando obtém facetas por nome, apenas são devolvidos os 10 valores que ocorrem com mais frequência para uma faceta.
Selecionar facetas por nome e valor
Para obter informações apenas sobre valores específicos de uma faceta, adicione um FacetDiscovery com o nome da faceta e os valores de interesse: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),
),
},
})
Os valores num único FacetDiscovery
têm de ser todos do mesmo tipo, ou seja, uma lista de valores search.Atom
ou, para números, uma lista de search.Range
, que são intervalos fechados à esquerda (início) e abertos à direita (fim). Se o seu filtro tiver uma combinação de valores de string e numéricos, adicione opções FacetDisovery
separadas para cada um.
Opções
Pode controlar o número mínimo de documentos a avaliar para recolher informações de facetas adicionando a opçãoFacetDocumentDepth
no SearchOptions
para a sua consulta.
Se não for especificada, esta profundidade é predefinida como 1000.
Tenha em atenção que a profundidade da faceta é normalmente muito superior ao limite de consultas. Os resultados das facetas são calculados para, pelo menos, o número de profundidade de documentos. Se tiver definido o limite de pontuação das opções de ordenação superior à profundidade, é usado o limite de pontuação.
A receber resultados de facetas
Quando usa parâmetros de pesquisa com filtros numa consulta, as informações de filtros agregadas são apresentadas com o próprio resultado da consulta.
A pesquisa Iterator
tem um método Facets
, que devolve as informações agregadas das facetas como [][]FacetResult
.
Os resultados estão organizados de modo que exista uma fatia de resultados de facetas para cada
faceta que apareceu num documento que correspondeu à sua consulta. Para cada resultado, recebe:
- O nome do aspeto
- Um valor para o aspeto da lista dos valores mais frequentes
- Uma contagem aproximada do número de vezes que esse valor apareceu
Tenha em atenção que a lista de valores inclui a string e os valores numéricos de uma faceta. Se o aspeto foi descoberto automaticamente, os respetivos valores numéricos são devolvidos como um único intervalo [min max). Se pediu explicitamente uma faceta numérica com um ou mais intervalos na sua consulta, a lista vai conter um intervalo fechado-aberto [início fim) para cada intervalo.
A lista de valores de facetas pode não incluir todos os valores encontrados nos seus documentos, uma vez que as opções de consulta determinam quantos documentos examinar e quantos valores devolver.
As informações agregadas para cada faceta podem ser lidas a partir do iterador:
it := index.Search(...)
facets, err := it.Facets() // And check err != nil.
for _, results := range facets {
for _, facet := range results {
...
}
}
Por exemplo, uma consulta pode ter encontrado documentos que incluíam uma faceta "tamanho" com os valores de string e os valores numéricos. Os resultados desta faceta são construídos da seguinte forma:
[][]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 refinar/filtrar uma consulta
Cada FacetResult
pode ser usado para restringir ainda mais os resultados de modo a incluir apenas documentos que tenham esses valores de faceta. Para refinar as consultas com uma ou mais destas chaves, transmita-as como opções de pesquisa:
it := index.Search(c, "...", &search.SearchOptions{
Refinements: []search.Facet{
facetResult1.Facet,
facetResult2.Facet,
},
})
Pode combinar refinamentos para uma ou mais facetas diferentes no mesmo pedido. Todos os refinamentos pertencentes à mesma faceta são unidos com um OR. Os refinamentos para diferentes facetas são combinados com AND.
Também é possível criar um Facet
personalizado manualmente para utilização como refinamento.
Consulte a referência para mais informações.