From: Rob V. <rv...@do...> - 2012-10-18 17:05:36
|
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 |
From: Tomasz P. <tom...@gm...> - 2012-10-18 18:35:27
|
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) 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? 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? 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") ); 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) { ... } 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? 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 > |
From: Rob V. <rv...@do...> - 2012-10-18 19:32:39
|
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 |
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 |
From: Rob V. <rv...@do...> - 2012-10-20 00:05:49
|
Hey Tom You would use it to combine multiple triple pattern builders into graph pattern builders in order to join and nest graph patterns together e.g. t1.Union(t2); Or: t1.Optional(t2); Or: t1.InGraph(new Uri("http://graph")); Or: t1.Minus(t2); The query builder would allow for either a triple pattern builder or a graph pattern builder to set the where clause. Similarly most of the above methods could either take a triple pattern builder or a graph pattern builder. Sorry for being vague but it's Friday afternoon and I'm about to head home for the weekend having only flown back into the country on Monday (yay jet lag and over tiredness) Rob On 10/19/12 8:05 AM, "Tomasz Pluskiewicz" <tom...@gm...> wrote: >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(ne >>>w >>>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 > >-------------------------------------------------------------------------- >---- >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 |
From: Tomasz P. <tom...@gm...> - 2012-10-25 19:04:07
|
Hi Thanks for your reply. I think I get the idea. I have some two questions/issues about graph patterns: 1. Why is it that new SparqlQuery has the RootGraphPattern null? It causes weird behaviour what I add an optional to a query first you would add the graph pattern as root. That produces an invalid query like SELECT * WHERE OPTIONAL { ... } Another problem there was that calling Where() after Optional() would add the additional triples to Optional instead the regular root pattern (because optional was added as root). For now I am making sure in the private QueryBuilder constructor that RootGraphPattern is initialized which helps. 2. I added a test where I first add an optional graph pattern and then call Where which adds some more pattern to root. However adding triple patterns to root causes an extra nesting, because adding optional breaks the root graph pattern. Is that necessary? How would I produce a graph pattern like: { OPTIONAL {...} ?s ?p ?o } instead of the current result: { OPTIONAL {...} { ?s ?p ?o } } Thanks Tom On Sat, Oct 20, 2012 at 2:04 AM, Rob Vesse <rv...@do...> wrote: > Hey Tom > > You would use it to combine multiple triple pattern builders into graph > pattern builders in order to join and nest graph patterns together > > e.g. > > t1.Union(t2); > > Or: > > t1.Optional(t2); > > Or: > > t1.InGraph(new Uri("http://graph")); > > Or: > > t1.Minus(t2); > > The query builder would allow for either a triple pattern builder or a > graph pattern builder to set the where clause. Similarly most of the > above methods could either take a triple pattern builder or a graph > pattern builder. > > Sorry for being vague but it's Friday afternoon and I'm about to head home > for the weekend having only flown back into the country on Monday (yay jet > lag and over tiredness) > > Rob > > On 10/19/12 8:05 AM, "Tomasz Pluskiewicz" <tom...@gm...> > wrote: > >>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(ne >>>>w >>>>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 >> >>-------------------------------------------------------------------------- >>---- >>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 |