Clone URL (Committers only): https://cms.apache.org/redirect?new=anonymous;action=diff;uri=http://jena.apache.org/documentation%2Fquery%2Fmanipulating_sparql_using_arq_pt.mdtext
Jonathas Alves Index: trunk/content/documentation/query/manipulating_sparql_using_arq_pt.mdtext =================================================================== --- trunk/content/documentation/query/manipulating_sparql_using_arq_pt.mdtext (revision 0) +++ trunk/content/documentation/query/manipulating_sparql_using_arq_pt.mdtext (working copy) @@ -0,0 +1,189 @@ +Title: Tutorial - Manipulando SPARQL usando ARQ +Notice: Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + . + http://www.apache.org/licenses/LICENSE-2.0 + . + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + +Quando você começa a trabalhar com SPARQL você rapidamente descobre que queries estáticas são restritivas. + Talvez você queira mudar um valor, adicionar um filtro, alterar o limite, etc. Sendo do tipo impaciente, +você começa a manipular a string da query e isso funciona. Mas o que dizer de little Bobby Tables? +Além do mais, mesmo que você limpe ao máximo suas entradas, manipulação de strings é um processo +tenso e erros de sintaxe esperam por você. Muito embora possa parecer mais difícil do que string munging, +a API ARQ é sua amiga na longa jornada. + +*Originalmente publicado em [Research Revealed project +blog](http://researchrevealed.ilrt.bris.ac.uk/?p=35)* + +## Inserindo valores (comandos simples prontos) + +Vamos começar com algo simples. Suponha que nós queiramos restringir a query a seguir a uma pessoa (person) em particular: + + select * { ?person <http://xmlns.com/foaf/0.1/name> ?name } + +`String#replaceAll` deveria funcionar, mas existe um jeito mais seguro. +`QueryExecutionFactory` em muitos casos, permite que você alimente uma `QuerySolution` +com a qual você pode prefixar valores. + + QuerySolutionMap initialBinding = new QuerySolutionMap(); + initialBinding.add("name", personResource); + qe = QueryExecutionFactory.create(query, dataset, initialBinding); + +Isto geralmente é muito mais simples do que a string equivalente desde que você não tenha usar aspas para +citações. (Esteja ciente de que isto não funciona para +`sparqlService`, o que é uma pena. Seria legal gastar algum tempo consertando isto.) + +## Fazendo uma Query a partir do zero + +As limitações previamente mencionadas se devem ao fato de que prefixação na verdade não muda a query em nada, +apenas a execução daquela query. Então, como nós realmente alteramos queries? + +ARQ provê duas maneiras de se trabalhar com queries: no nível de sintaxe (`Query` +and `Element`), ou no nível algébrico (`Op`). A distinção entre eles fica claro com os filtros: + + SELECT ?s { ?s <http://example.com/val> ?val . FILTER ( ?val < 20 ) } + +Se você trabalha no nível de sintaxe, você irá descobrir que isso (em pseudo código) se parece com : + + (GROUP (PATTERN ( ?s <http://example.com/val> ?val )) (FILTER ( < ?val 20 ) )) + +Isto é, existe um grupo contendo um padrão triplo e um filtro, do mesmo jeito que você vê na query. +A álgebra é diferente e nós podemos vê-la usando `arq.qparse --print op` + + $ java arq.qparse --print op 'SELECT ?s { ?s <http://example.com/val> ?val . FILTER ( ?val < 20 ) }' + (base <file:///...> + (project (?s) + (filter (< ?val 20) + (bgp (triple ?s <http://example.com/val> ?val))))) + +Aqui o filtro contém o padrão, ao invés de se situar próximo a ele. Esta forma torna claro que a expressão +está filtrando o padrão. + +Vamos criar esta query do zero usando ARQ. Nós começamos com algumas partes comuns: a tripla a ser comparada +e a expressão a ser filtrada. + + + // ?s ?p ?o . + Triple pattern = + Triple.create(Var.alloc("s"), Var.alloc("p"), Var.alloc("o")); + // ( ?s < 20 ) + Expr e = new E_LessThan(new ExprVar("s"), new NodeValueInteger(20)); + +`Triple` deveria ser familiar de Jena. `Var` é uma extensão de `Node` +para variáveis. `Expr` é a interface raíz para expressões, aquelas coisas que aparecem em `FILTER` and `LET`. + +Primeiro, o caminho da sintaxe: + + ElementTriplesBlock block = new ElementTriplesBlock(); // Make a BGP + block.addTriple(pattern); // Add our pattern match + ElementFilter filter = new ElementFilter(e); // Make a filter matching the expression + ElementGroup body = new ElementGroup(); // Group our pattern match and filter + body.addElement(block); + body.addElement(filter); + + Query q = QueryFactory.make(); + q.setQueryPattern(body); // Set the body of the query to our group + q.setQuerySelectType(); // Make it a select query + q.addResultVar("s"); // Select ?s + +Agora a álgebra: + + Op op; + BasicPattern pat = new BasicPattern(); // Make a pattern + pat.add(pattern); // Add our pattern match + op = new OpBGP(pat); // Make a BGP from this pattern + op = OpFilter.filter(e, op); // Filter that pattern with our expression + op = new OpProject(op, Arrays.asList(Var.alloc("s"))); // Reduce to just ?s + Query q = OpAsQuery.asQuery(op); // Convert to a query + q.setQuerySelectType(); // Make is a select query + +Note que o tipo da query (`SELECT, CONSTRUCT, DESCRIBE, ASK`)não é parte da álgebra, +e que nós temos que configurar isso na query (embora SELECT seja o padrão). `FROM` e `FROM NAMED` +estão igualmente ausentes. + +## Navegando e Aprendendo: Visitors + +Você também pode olhar para a álgebra e a sintaxe usando vistors. Comece estendendo `OpVisitorBase` +(`ElementVisitorBase`) que apaga a interface de modo que você pode se concentrar nas partes de interesse, +então dê um passo a frente e use `OpWalker.walk(Op, OpVisitor)` +(`ElementWalker.walk(Element, ElementVisitor)`). Isso funciona no esquema “bottom up” (de baixo para cima). + +Para algumas alterações, como manipulação de padrões triplos no local, visitors irão trabalhar bem. + Eles provêm um jeito simples de manipular as partes certas da query e você pode alterar as BGPs backing + padrões tanto na álgebra quanto na sintaxe. Entretanto, mutações (mutation) não estão consistentemente + disponíveis, não conte com elas. + +## Transformando a Álgebra + +A primeira vista, não há vantagens óbvias em usar a álgebra. O real poder fica claro com o uso de +transformers (transformações), que lhe permitem reorganizar uma álgebra completamente. ARQ faz amplo +uso de transformers para simplificar e aperfeiçoar execuções de query. + +Em Research Revealed (Pesquisa revelada, em tradução livre), eu escrevi algum código para pegar certo +número de constraints (constantes) e produzir uma query. Havia várias formas de se fazer isto, mas o +jeito que eu achei foi gerar ops de cada constraint e juntar o resultado. + + for (Constraint con: cons) { + op = OpJoin.create(op, consToOp(cons)); // join + } + +O resultado foi uma bagunça incrivelmente correta, que é remotamente compreensível em apenas três condições: + + (join + (join + (filter (< ?o0 20) (bgp (triple ?s <urn:ex:prop0> ?o0))) + (filter (< ?o1 20) (bgp (triple ?s <urn:ex:prop1> ?o1)))) + (filter (< ?o2 20) (bgp (triple ?s <urn:ex:prop2> ?o2)))) + +Cada uma das constraints é um filtro e um bgp. Isso pode ser muito mais compreensível removendo os + filtros e juntando (merging) os padrões triplos. Nós podemos fazer isso usando `Transform`: + + class QueryCleaner extends TransformBase + { + @Override + public Op transform(OpJoin join, Op left, Op right) { + // Bail if not of the right form + if (!(left instanceof OpFilter && right instanceof OpFilter)) return join; + OpFilter leftF = (OpFilter) left; + OpFilter rightF = (OpFilter) right; + + // Add all of the triple matches to the LHS BGP + ((OpBGP) leftF.getSubOp()).getPattern().addAll(((OpBGP) rightF.getSubOp()).getPattern()); + // Add the RHS filter to the LHS + leftF.getExprs().addAll(rightF.getExprs()); + return leftF; + } + } + ... + op = Transformer.transform(new QueryCleaner(), op); // clean query + +O código abaixo procura pelos joins do formulário: + + (join + (filter (exp1) (bgp1)) + (filter (exp2) (bgp2))) + +E substitui ele com: + + (filter (exp1 && exp2) (bgp1 && bgp2)) + +Enquanto nós percorremos a query original, todos os joins são removidos e o resultado final é: + + (filter (exprlist (< ?o0 20) (< ?o1 20) (< ?o2 20)) + (bgp + (triple ?s <urn:ex:prop0> ?o0) + (triple ?s <urn:ex:prop1> ?o1) + (triple ?s <urn:ex:prop2> ?o2) + )) +Isto completa esta breve introdução. Existe muito mais em ARQ, claro, mas esperamos que você tenha tido um gostinho do que ele pode fazer. \ No newline at end of file Property changes on: trunk/content/documentation/query/manipulating_sparql_using_arq_pt.mdtext ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property
