Space Vatican

quando você está indexando dados, o mundo raramente é tão simples quanto cada documento existente em isolamento. Às vezes, é melhor desnormalizar todos os dados para os documentos das crianças. Por exemplo, se você estava modelando livros, adicionar um campo autor a livros poderia ser uma escolha sensata (mesmo que na base de dados que é sua fonte de dados autoritária os dados são divididos em separado authors e books tabela). É simples e você pode facilmente construir consultas sobre ambos os atributos do livro e o nome do autor.

isso nem sempre é prático – pode haver muitos dados no documento pai para duplicá-lo em cada documento filho. Se você tivesse o seu típico aplicativo de blog/comentário, então você não iria querer repetir todo o conteúdo do blog post em cada comentário, pois isso aumentaria muito a quantidade de dados indexados vários. No entanto, sem isso, você não pode facilmente escrever consultas para encontrar comentários sobre posts que correspondam a certos critérios (além de fazer um 2 passo de processo de primeiro encontrar posts correspondentes e, em seguida, obter comentários com um certo post_id, que é muitas vezes difícil ou lento (ou ambos).

Outra opção é colocar a criança documentos dentro do documento pai, por exemplo, podem ter documentos de forma

123456789101112
{ "name": "A. N Author", "biography": "A leading wordsmith", "books": }

Uma desvantagem aqui é que a adição de uma criança requer reindexação o documento inteiro. Encontrar autores que tenham escrito livros com um certo gênero é fácil, mas encontrar autores que tenham tido um livro de ficção científica publicado pelo penguin é mais difícil.Se o nosso índice contiver

então a consulta mais óbvia

encontra ambos os autores-você não pode expressar que suas condições em published e genre precisam se comparar com o mesmo livro.

ElasticSearch provides two things that help with this. O primeiro é o conceito de um documento aninhado/consulta. Isto permite-lhe dizer que está à procura de autores onde pelo menos um livro satisfaz ambos os seus critérios.

Primeiro você precisa configurar um mapeamento que diz que os livros de campo vai ser aninhados:

123456789
curl -XPOST localhost:9200/authors/nested_author/_mapping -d '{ "nested_author":{ "properties":{ "books": { "type": "nested" } } }}'

Se nós, em seguida, inserir os mesmos dados como antes com esse novo índice, em seguida, esta consulta

Aqui nested filtro permite que você executar uma consulta em relação a documentos aninhados (ou seja, a livros) e filtro de autores por aqueles que têm pelo menos um aninhados documento de correspondência de consulta. A opção path diz – nos a que parte dos autores esta consulta se aplica e então a opção query é uma consulta para correr contra estes documentos aninhados. Ao contrário da consulta anterior, isso requer que um livro individual seja encontrado satisfazendo ambos os requisitos, de modo que apenas Alaistair Reynolds é devolvido

Pai & filho

o outro conceito elasticsearch fornece é o de uma relação pai-filho entre documentos. O exemplo anterior pode ser retrabalhado com os autores como os documentos dos pais e livros como os documentos das crianças.

desta vez, indexe os autores separadamente de seus livros:

então configure o mapeamento para o tipo de livro e diga que seu tipo-mãe é bare_author. Tens de fazer isto antes de criares livros.

12345
curl -XPOST localhost:9200/authors/book/_mapping -d '{ "book":{ "_parent": {"type": "bare_author"} }}'

Quando nós indexação de livros, você deve, em seguida, atribua o id de seu pai (ou seja, nós fornecer o id de um dos criados anteriormente autores)

Elasticsearch fornece um has_child filtro que faz muito bem o que é que diz na lata: ele seleciona documentos-pai com pelo menos um filho satisfazendo uma determinada consulta. Esta consulta então encontra apenas Alastair Reynolds:

Solr 4.0 aparentemente terá a capacidade de fazer joins, embora tanto quanto eu posso dizer isso vem com algumas restrições, em particular nenhuma junção se você é operado em um ambiente distribuído. Ao limitar-se a relacionamentos de tipo pai/filho, elasticsearch torna a vida mais fácil para si mesmo: uma criança é sempre indexada no mesmo fragmento que seu pai, então has_child não tem que fazer operações de corte cruz constrangedoras.

listas de edifícios

também pode usar isto para modelar listas específicas de itens globais partilhados pelo Utilizador – por exemplo, se quiser itens que um utilizador tenha avaliado. Neste caso, seus documentos filhos representariam o fato de que um usuário específico tinha classificado um post específico – eles não são nada mais do que um user_id, post_id e uma classificação: uma tabela de junção na linguagem de banco de dados relacional.

usando uma relação pai / filho e has_child permite-lhe encontrar facilmente todos os posts favorecidos por um utilizador, ao mesmo tempo que permite aos utilizadores pesquisar através dos seus favoritos com base no conteúdo do post, na data ou em qualquer outro dos atributos de um post ou em qualquer das propriedades do item filho. Adicionar um item à lista de itens classificados é barato-ele requer apenas indexar um item muito pequeno rating.

com estes documentos

esta consulta

encontra apenas “bolivia rated 4” uma vez que este é o único post que menciona a Bolívia que foi classificado acima de 3 pelo usuário em que estamos interessados. A consulta de nível superior no título aplica-se a cargos, considerando que a consulta dentro de has_child filtro descreve as condições que as crianças devem coincidir (neste caso, elas devem pertencer a um usuário específico e ter pelo menos uma certa classificação).

Ordenar

o que has_child não permite que você faça é ordem baseada em atributos das crianças ou atributos de retorno da criança. Se você queria encomendar posts classificados de um usuário com base em quando eles foram classificados ou diminuindo a classificação, então você pode pesquisar contra posts/classificação diretamente, mas você pode querer aplicar alguns critérios de pesquisa para os posts também. Por exemplo, você pode querer apenas encontrar posts classificados em um determinado tópico (ainda ordenando pela classificação que o Usuário deu). Com has_child, estás sem sorte. Os documentos aninhados também não ajudam.

a partir de 0.19.10 pode utilizar o filtro has_parent. Isso funciona quase exatamente o mesmo que tem filho, mas permite que você especifique uma consulta contra os itens pai em vez disso. Esta consulta retorna as classificações pelo Usuário 1234, em posts cujo título corresponde a “Bolívia”, em ordem decrescente de pontuação

isto retorna os objetos de classificação – você teria que então obter as publicações correspondentes com uma consulta separada.Se você está preso em uma versão mais antiga da pesquisa elastica, você pode obter a maior parte do caminho até lá com top_children. Como a documentação diz top_children primeira consulta os documentos do Filho e, em seguida, agregá-los em documentos do Pai. No nosso exemplo, isto significa que a elasticsearch irá primeiro encontrar os documentos de classificação que correspondem à nossa consulta. Em seguida, ele vai combinar cada classificação para o seu post pai, agregando post duplicado onde eles existem.

the fiddly bit with top children is that elasticsearch doesn’t know ahead of time how many documents it will lose when the aggregation happens. Neste caso particular é fácil porque duas classificações distintas pelo mesmo usuário sempre correspondem a duas postagens distintas, então não precisamos nos preocupar com configurações factor e incremental_factor porque a fase de agregação nunca faz nada. Da mesma forma, o modo de pontuação também não importa. Se você precisar fornecer uma contagem precisa do número total de resultados que você só precisa definir factor grande o suficiente para que a primeira busca elastica varre todos os documentos da criança encontra todos eles. Se você sabe que o usuário tem 500 itens classificados em sua lista e você está pedindo os primeiros 10 itens, então um fator de 50 deve fazer o truque. Factor só precisa ser um limite superior-você não precisa saber exatamente quantos itens o usuário tem em sua lista (o que pode ser estranho para funcionar sem uma pesquisa elástica separada se o usuário está procurando um subconjunto específico de suas classificações).

o que você recebe depois de tudo isso é uma lista de documentos pais (posts) ordenados pela Pontuação da consulta dos documentos filhos (ratings). Para alcançar o objetivo original de classificar os posts com base nos atributos dos documentos das crianças, só precisamos garantir que esta pontuação de consulta tem o valor certo. Por exemplo, tenha top_children query wrap uma custom_score query de modo que você tenha controle sobre qual é a pontuação para cada criança.

com os mesmos documentos no índice, esta consulta devolve as mensagens que o utilizador 1234 avaliou, ordenadas pela sua classificação:

estamos executando uma consulta top_children , então a primeira coisa que precisamos fazer é dizer qual é o tipo de crianças que estamos considerando (classificação). Então nós fornecemos a consulta que encontra essas crianças. Esta é uma consulta custom_score, envolvendo uma consulta filtered. A consulta filtered garante que só encontramos classificações dadas pelo usuário em que estamos interessados, e, em seguida, o elemento script faz com que a pontuação do documento de classificação seja a classificação em si, de modo que nós obter nossos posts classificados por classificação. A estranheza com os backslashes é apenas porque estou tentando incluir uma citação literal em uma cadeia amigável shell delimitada por citações simples – o json real que estamos enviando tem apenas "script": "doc.value".

Ruby diversão

Infelizmente o pneu biblioteca realmente não apoio qualquer dessas coisas divertidas no momento – há um pouco de uma moratória sobre este tipo de recurso a ser adicionado porque no momento em que cada pouco o tipo de consulta e opção acaba sendo separado métodos espalhados por todo o pneu, que é o mantenedor, compreensivelmente, não gosta. Mas podes hackeá-lo.

pneu não permite que você defina o id pai de um documento ao indexar. Isto é simples de acrescentar e só está a ser retido pela referida moratória. O meu garfo acrescenta esta habilidade. Com isso você acaba com

o próximo bit de infelicidade é que a criação auto índice de Pneu pressupõe um tipo por índice, mas para que um relacionamento pai/filho para existir ambos os tipos têm que estar no mesmo índice. Acabei por fazer uma coisa destas para criar os meus índices.

o que não é tão bonito, mas faz o trabalho feito.

finalmente você precisa realmente fazer a consulta. Na ausência de top_children na verdade, sendo a parte do pneu do api que você pode fudge-lo assim

Este pouco de desagrado constrói a consulta como um hash e, em seguida, empurra-lo para dentro do pneu, enquanto ele está olhando para o outro. Obviamente você pode estruturá-lo de tal forma que é fácil adicionar outras condições (seja no Post ou na classificação) para a pesquisa. Você também pode construir o json manualmente e usar Post.search :payload => my_json (há um bug com a opção de carga que entra em conflito com a extensão de Logger do pneu-contrib)

Deixe uma resposta

O seu endereço de email não será publicado.