From: Tomasz P. <tom...@gm...> - 2012-10-19 15:06:49
|
Hi Rob I have been pondering your idea of IGraphPatternBuilder but I'm not sure I understand. Could you give an example of how you would design it's API? Thanks, Tom On Thu, Oct 18, 2012 at 9:31 PM, Rob Vesse <rv...@do...> wrote: > Hey Tom > > That all looks great, comments inline > > On 10/18/12 11:34 AM, "Tomasz Pluskiewicz" <tom...@gm...> > wrote: > >>Hi Rob >> >>Actually I have just today been preparing an email to agree on the >>fluent API. Here it goes. >> >>I have been thinking about the shape of the fluent query API and I >>would like to propose some changes. >> >>1. Currently there are quite a few overloads of the Where method. I >>think the API will be more usable if we left only a limited number, >>eg. >> >>* IQueryBuilder#Where(params ITriplePattern[] patterns) >>* IQueryBuilder#Where(params Triple[] triples) - not sure about >>triples here though >>* IQueryBuilder#Where(GraphPattern) > > Yes I agree having a simpler high level interface for building queries is > better > >> >>Regarding the ast overload, what are the ways to create graph >>patterns? I mean I have seen the ToGraphPattern() method here and >>there. Which classes define such a method and what are differences in >>the graph patterns they produce? > > ToGraphPattern() is typically on algebra classes but it not reliable > because > some algebras (particularly those generated by optimization) cannot be > converted to graph patterns. > > Basically graph pattern wise you have the following: > > - Normal > - OPTIONAL > - GRAPH > - UNION > - SERVICE > - MINUS > - EXISTS/NOT EXISTS (within FILTER only) > >> >>2. I think the API should expose functionality but with least required >>use of the internal SPARQL types like the ITriplePattern, >>ISparqlExpression and such. I would not remove it of course to leave >>room for flexibility. For a day-to-day query building I think that >>maybe creating triple patterns should be split into subjects, >>predicates, object and possibly graphs (here this posin overlaps the >>above about GraphPatterns). As such it sould be possible to implement >>less code and at the same time give a greater flexibility for the user >>and remove the burden of creating instances of the SparqlVariable >>class and such. For example: >> >>var prefixes = new NamespaceMapped(); >>// set up prefixes ... >> >>IQueryBuilder query = QueryBuilder.Select("person", "name"); >> >>// I have just made this up, but could be useful although string name >>interfere with >>// QNames. Maybe add a struct QName? >>query.UsePrefixesFrom(prefixes); >> >>2a. >>// a more flexible form of triple pattern building >>// note the RdfType mehod. This way it would could provide some common >>// properties/classes and also leave an opening for users to create >>their own extension methods >>query.Where.Subject("person").RdfType().Object(new QName("foaf:Person")); >> >>2b. >>// alternatively there's a proposal without the QName struct/class, >>which I like more >>query.Where.Subject("person").RdfType().Object<IUriNode>("foaf:Person")); >> >>2c. >>// here NodeMatchPattern for predicate with full Uri given and obejct >>as a VariablePattern >>query.Where.Subject("person").Predicate(new >>Uri("http://xmlns.com/foaf/0.1/name")).Object("name")); >> >>In terms of graphs, I think that maybe we could provide one more >>method to such ITripleVariable-producing chain, to select the >>appropriate named graph pattern >> >>2d. >>query.Where.Subject("person").Predicate(new >>Uri("http://xmlns.com/foaf/0.1/firstName")).Object("name")).InGraph(new >>Uri("http://uri/of/graph")); >>query.Where.Subject("person").Predicate(new >>Uri("http://xmlns.com/foaf/0.1/lastName")).Object("surname")).InGraph(new >>Uri("http://uri/of/graph")); >>query.Optional.Subject("person").Predicate<IUriNode>("foaf:mbox_sha1sum"). >>Object("emailSha1")).InGraph(new >>Uri("http://uri/with/contact/data")); >> >>All the above would produce: >> >>ad 2a/2b and 2c >> >>WHERE >>{ >> ?person a foaf:Person . >> ?person foaf:name ?name . >>} >> >>ad 2d >> >>WHERE >>{ >> # calling InGraph() with same parameter should >> # add triple pattern to same graph pattern, right? > > Yes that would make sense, implementing it might be slightly trickier but > the notion is sound > > Perhaps InGraph() would turn a ITriplePatternBuilder into a > IGraphPatternBuilder and the user > would have the option of adding further triple/graph pattern builders to > an existing one > >> GRAPH <http://uri/of/graph> >> { >> ?person foaf:firstName ?name >> ?person foaf:lastName ?surname >> } >> GRAPH <http://uri/with/contact/data> >> { >> OPTIONAL { ?person foaf:mbox_sha1sum ?name } >> } >>} >> >>Not how the OPTIONAL has API equivalent to WHERE >> >>3. I have also been thinking that a simmilar way could be used to >>create CONSTRUCT queries. However with the current static >>initialization of query builder I would suggest slightly modifying the >>above to reuse the same methods in both scenarios >> >>One way I find quite good could be using an Action<> delegate and >>introducing an ITriplePatternBuilder interface to actually build the >>triple patterns: >> >>var query = QueryBuilder.Construct( >> (ITriplePatternBuilder tp) => >>tp.Subject("person").RdfType().Object<IUriNode>("ex:MyPersonClass") >>); > > I like this approach, it's clean and extensible > > I assume we'd have ITriplePatternBuilder, maybe IGraphPatternBuilder and > likely a IExpressionBuilder ? > >> >>With this approach, the Where/Optional would change to: >> >>query.Where( tp => >>tp.Subject("person").RdfType().Object<IUriNode>("foaf:Person")) ); >> >>and internally bouth would look somewhat like: >> >>public IQueryBuilder Where(Action<ITriplePatternBuilder> >>buildTriplePatterns) >>{ >> var builder = new TriplePatternBuilder(); //implementation internal >> buildTriplePatterns(builder); >> return Where(builder.TriplePatterns.ToArray()); >>} >> >>I think this way we get a clean seperation of concerns, good >>testability and room for extensibility. >> >>4. Ask query is trivial. The SPARQL update could also use the proposed >>ITriplePatternBuilder I think >> >>5. Basic federated queries could be achived in a simmilar way the >>InGraph() method is used above for >> >>6. We need a method for the BIND keyword, eg. >> >>public IQueryBuilderBind(ISparqlExpression expression, string >>variableName) { ... } > > There could maybe just be a method on the ITriplePatternBuilder to create > a BIND, possible also similar for FILTER and so forth > >> >> >> >>Oh well, there is much more, but we have enough to discuss just for >>now. Tell me what are your feelings about all the above. You are >>certainly more experienced with SPARQL so I would be greateful for >>your own ideas for this feature, which I'm sure you have :). >> >>Also, what do you think would be the greatest challenges here? > > I don't think anything sounds too hard, the tricky bit is just ensuring > you turn these into triple/graph patterns in a consistent manner which > makes sense from the point of the user. We need to be making sure things > group and nest in predictable and appropriate ways e.g. calling InGraph() > creates all the triple patterns from it's builder in a single GRAPH > pattern rather than into multiple GRAPH patterns if that makes sense > > Sounds like you have a good idea what you are doing so I will leave you to > get on with it for the time being. > > One thought I did have is that it probably isn't necessary to have > everything explicitly implement INodeFactory (even SparqlQuery), what > would be simpler is just to have the builders that do need to generate > nodes just extend NodeFactory (and thus get a pre-build implementation of > INodeFactory) though given your above proposal it may turn out that making > the builders be node factories is entirely unnecessary and you can just > have a private NodeFactory for use within the builders. > > Rob > >> >>Thanks, >>Tom >> >>On Thu, Oct 18, 2012 at 7:04 PM, Rob Vesse <rv...@do...> wrote: >>> Hey Tom >>> >>> Can you send me a pull request for what you have so far on the >>>fluent-query >>> branch? >>> >>> I've finished up the refactor I was working on so have some more time to >>> look at the fluent-query work if you'd like some help >>> >>> Cheers, >>> >>> Rob >>> >>> >>>------------------------------------------------------------------------- >>>----- >>> Everyone hates slow websites. So do we. >>> Make your web apps faster with AppDynamics >>> Download AppDynamics Lite for free today: >>> http://p.sf.net/sfu/appdyn_sfd2d_oct >>> _______________________________________________ >>> dotNetRDF-develop mailing list >>> dot...@li... >>> https://lists.sourceforge.net/lists/listinfo/dotnetrdf-develop >>> >> >>-------------------------------------------------------------------------- >>---- >>Everyone hates slow websites. So do we. >>Make your web apps faster with AppDynamics >>Download AppDynamics Lite for free today: >>http://p.sf.net/sfu/appdyn_sfd2d_oct >>_______________________________________________ >>dotNetRDF-develop mailing list >>dot...@li... >>https://lists.sourceforge.net/lists/listinfo/dotnetrdf-develop > > > > > > ------------------------------------------------------------------------------ > Everyone hates slow websites. So do we. > Make your web apps faster with AppDynamics > Download AppDynamics Lite for free today: > http://p.sf.net/sfu/appdyn_sfd2d_oct > _______________________________________________ > dotNetRDF-develop mailing list > dot...@li... > https://lists.sourceforge.net/lists/listinfo/dotnetrdf-develop |