Há pouco tempo, escrevi sobre como trabalhar com partes ou fragmentos de documentos no Couchbase
usando o SDK do Node.js. Ser capaz de trabalhar com
partes de documentos é possível usando
Servidor Couchbase 4.5 e superior e a API do subdocumento.
Isso é muito importante porque, ao trabalhar com documentos NoSQL, você pode se deparar com documentos muito grandes devido a todos os dados JSON incorporados. Como você provavelmente
Sabe-se que fazer solicitações em documentos grandes é lento e, na era moderna da Web, tudo precisa ser rápido. Em vez disso, é mais eficiente apenas
Trabalhe com o que você precisa e não com tudo de uma vez.
Desta vez, vamos tentar fazer as mesmas manipulações de documentos NoSQL que vimos no Node.js, mas, desta vez, com a linguagem de programação Go. Vamos lá
criar uma história de dados para este exemplo. Será a mesma história de dados do exemplo anterior, mas vamos supor que temos o seguinte documento JSON:
1 2 3 4 5 6 7 8 9 |
{ firstName: "Nic", lastName: "Raboy", redes sociais: { twitter: "nraboy" } } |
Os dados acima serão uma base armazenamento de perfil de usuário com informações de mídia social. Todas as nossas manipulações serão em torno das informações de mídia social, não
os dados principais que o cercam.
Para simplificar este guia, vamos trabalhar com um projeto novo. Neste ponto, presumiremos que você tenha o Couchbase Server 4.5+ e o
GoLang instalado e configurado em seu computador. Se você ainda não baixou o GoLang SDK para o Couchbase, execute o seguinte em seu comando
Prompt ou Terminal:
1 2 3 |
ir obter github.com/couchbase/gocb |
Todo o nosso projeto para este exemplo residirá em um único arquivo. Vamos nos referir a esse arquivo como main.go e pode residir em qualquer
O diretório do projeto Go que você quiser, desde que atenda aos requisitos da linguagem de programação Go.
Para começar, vamos criar um arquivo principal
dentro do nosso projeto:
1 2 3 4 5 6 7 8 9 |
func principal() { fmt.Println("Iniciando o aplicativo...") agrupamento, _ := gocb.Conectar("couchbase://localhost") balde, _ = agrupamento.OpenBucket("default", "") pessoa := Pessoa{FirstName: "Nic", Sobrenome: "Raboy", Redes sociais: &lificador;Redes sociais{Twitter: "nraboy"}} createDocument("nraboy", &lificador;pessoa) } |
Há alguns aspectos a serem observados no exemplo acima. Primeiro, estamos estabelecendo uma conexão com um cluster do Couchbase em execução local. Quando a conexão tiver
estabelecido, abrimos o padrão
balde. Observe que estamos atribuindo apenas um valor à variável balde
e não o define. Isso
é porque vamos usar essa variável globalmente e devemos defini-la fora do principal
função. Com o balde aberto, vamos
criar nossa estrutura de dados inicial. Essa estrutura de dados Pessoa
é definido abaixo:
1 2 3 4 5 6 7 8 9 10 11 12 |
tipo Pessoa estrutura { FirstName string `json:"firstname,omitempty"` Sobrenome string `json:"lastname,omitempty"` Redes sociais *Redes sociais `json:"socialNetworking,omitempty"` } tipo Redes sociais estrutura { Twitter string `json:"twitter,omitempty"` Site string `json:"website,omitempty"` } |
O Pessoa
terá as informações básicas do usuário e fará referência a outra estrutura chamada Redes sociais
. Ambos
são marcadas com nomes de propriedades JSON que devem ser excluídas da impressão se estiverem em branco.
Voltando ao principal
função. Observe que nosso novo objeto de pessoa não tem o website. Adicionaremos isso mais tarde. O primeiro
que chamamos na função principal
é chamada de função createDocument
e ele adicionará nosso objeto ao banco de dados. Esta função
é definido da seguinte forma:
1 2 3 4 5 6 7 8 9 10 11 12 |
func createDocument(documentId string, pessoa *Pessoa) { fmt.Println("Inserção ascendente de um documento completo...") _, erro := balde.Upsert(documentId, pessoa, 0) se erro != nulo { fmt.Println(erro.Erro()) retorno } getDocument(documentId) getSubDocument(documentId) } |
Na função acima, ainda não estamos trabalhando com fragmentos de um documento. Primeiro, precisamos iniciar o exemplo com dados novos. Vamos inserir
o documento inicial e, se não houver erros, chamaremos getDocument
para validar sua criação e, em seguida
getSubDocument
para obter uma determinada parte do documento. O getDocument
será usada duas vezes neste aplicativo e a função
ele se parece com o seguinte:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
func getDocument(documentId string) { fmt.Println("Obtendo o documento completo por identificação...") var pessoa Pessoa _, erro := balde.Obter(documentId, &lificador;pessoa) se erro != nulo { fmt.Println(erro.Erro()) retorno } jsonPerson, _ := json.Marechal(&lificador;pessoa) fmt.Println(string(jsonPerson)) } |
No exemplo acima getDocument
estamos obtendo o documento inteiro com base no id, transformando-o em JSON e, em seguida, imprimindo-o. Essa função
nos leva ao getSubDocument
conforme mostrado abaixo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
func getSubDocument(documentId string) { fmt.Println("Obtendo parte de um documento por id...") fragmento, erro := balde.Pesquisa(documentId).Obter("socialNetworking").Executar() se erro != nulo { fmt.Println(erro.Erro()) retorno } var redes sociais Redes sociais fragmento.Conteúdo("socialNetworking", &lificador;redes sociais) jsonSocialNetworking, _ := json.Marechal(&lificador;redes sociais) fmt.Println(string(jsonSocialNetworking)) upsertSubDocument(documentId, "thepolyglotdeveloper.com") } |
No exemplo acima getSubDocument
estamos fazendo uma pesquisa em um documento para uma propriedade específica. É aqui que começamos a trabalhar com
a API do subdocumento. A pesquisa que estamos realizando é uma pesquisa para o redes sociais
propriedade. Observe que estou me referindo ao JSON, não ao
o estrutura
nome. Quando tivermos o fragmento, podemos transformá-lo em JSON e depois imprimi-lo. O resultado deve ser semelhante a este:
1 2 3 4 5 |
{ "twitter": "nraboy" } |
No final do getSubDocument
fazemos uma chamada para uma função a ser criada em breve upsertSubDocument
função. É aqui que
vamos modificar parte de um documento sem antes obter o documento inteiro. Essa função pode ser vista da seguinte forma:
1 2 3 4 5 6 7 8 9 10 11 |
func upsertSubDocument(documentId string, site string) { fmt.Println("Inserção ascendente de parte de um documento...") _, erro := balde.Mutação(documentId, 0, 0).Upsert("socialNetworking.website", site, verdadeiro).Executar() se erro != nulo { fmt.Println(erro.Erro()) retorno } getDocument(documentId) } |
Na função acima, primeiro especificamos qual documento queremos manipular com base no ID do documento. Em seguida, dizemos que queremos fazer um upsert em um
determinado caminho ou propriedade do documento. Neste exemplo, estamos dizendo que queremos inserir um site
encontrada na propriedade
redes sociais
pai. Observe que todo esse processo ocorre sem a obtenção efetiva do documento.
Quando terminarmos, faremos uma pesquisa completa do documento novamente para ver como ele se parece como um todo. Caso você precise que isso seja colocado em perspectiva, um
Melhor ainda, o código completo desse projeto pode ser visto abaixo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
pacote principal importação ( "encoding/json" "fmt" "github.com/couchbase/gocb" ) var balde *gocb.Balde tipo Pessoa estrutura { FirstName string `json:"firstname,omitempty"` Sobrenome string `json:"lastname,omitempty"` Redes sociais *Redes sociais `json:"socialNetworking,omitempty"` } tipo Redes sociais estrutura { Twitter string `json:"twitter,omitempty"` Site string `json:"website,omitempty"` } func getDocument(documentId string) { fmt.Println("Obtendo o documento completo por identificação...") var pessoa Pessoa _, erro := balde.Obter(documentId, &lificador;pessoa) se erro != nulo { fmt.Println(erro.Erro()) retorno } jsonPerson, _ := json.Marechal(&lificador;pessoa) fmt.Println(string(jsonPerson)) } func createDocument(documentId string, pessoa *Pessoa) { fmt.Println("Inserção ascendente de um documento completo...") _, erro := balde.Upsert(documentId, pessoa, 0) se erro != nulo { fmt.Println(erro.Erro()) retorno } getDocument(documentId) getSubDocument(documentId) } func getSubDocument(documentId string) { fmt.Println("Obtendo parte de um documento por id...") fragmento, erro := balde.Pesquisa(documentId).Obter("socialNetworking").Executar() se erro != nulo { fmt.Println(erro.Erro()) retorno } var redes sociais Redes sociais fragmento.Conteúdo("socialNetworking", &lificador;redes sociais) jsonSocialNetworking, _ := json.Marechal(&lificador;redes sociais) fmt.Println(string(jsonSocialNetworking)) upsertSubDocument(documentId, "thepolyglotdeveloper.com") } func upsertSubDocument(documentId string, site string) { fmt.Println("Inserção ascendente de parte de um documento...") _, erro := balde.Mutação(documentId, 0, 0).Upsert("socialNetworking.website", site, verdadeiro).Executar() se erro != nulo { fmt.Println(erro.Erro()) retorno } getDocument(documentId) } func principal() { fmt.Println("Iniciando o aplicativo...") agrupamento, _ := gocb.Conectar("couchbase://localhost") balde, _ = agrupamento.OpenBucket("default", "") pessoa := Pessoa{FirstName: "Nic", Sobrenome: "Raboy", Redes sociais: &lificador;Redes sociais{Twitter: "nraboy"}} createDocument("nraboy", &lificador;pessoa) } |
Faça um test drive neste projeto para ver como a API de subdocumentos é maravilhosa.
Conclusão
Você acabou de ver como usar a API de subdocumento do Couchbase Server em um aplicativo GoLang usando o Couchbase Go SDK. Você não precisará mais se preocupar com
passando por seus documentos NoSQL potencialmente enormes, arruinando os tempos de resposta do aplicativo. Se você sabe que seus documentos são grandes ou se precisa apenas de
você pode usar essa API.
Para obter mais informações, visite o site do Couchbase Portal do desenvolvedor.