marklogic / marklogic-jena

Adapter for using MarkLogic with the Jena RDF Framework
Other
5 stars 11 forks source link

REGR construct with binding returning empty result set #23

Closed kkanthet closed 8 years ago

kkanthet commented 9 years ago

Construct with binding returning empty results after the fix for #21

Node newgraph = NodeFactory.createURI("http://marklogic.com/graph1");

        dataSet = DatasetFactory.create(markLogicDatasetGraph);

        markLogicDatasetGraph.add(null, NodeFactory.createURI("john"), NodeFactory.createURI("fname"), NodeFactory.createURI("johnfname"));

        markLogicDatasetGraph.add(newgraph, NodeFactory.createURI("john"), NodeFactory.createURI("fname"),
                NodeFactory.createURI("johnfname"));
        markLogicDatasetGraph.add(newgraph, NodeFactory.createURI("john"), NodeFactory.createURI("lname"),
                NodeFactory.createURI("johnlname"));
        markLogicDatasetGraph.add(newgraph, NodeFactory.createURI("john"), NodeFactory.createURI("homeTel"),
                NodeFactory.createURI("111111111D"));
        markLogicDatasetGraph.add(newgraph, NodeFactory.createURI("john"), NodeFactory.createURI("email"),
                NodeFactory.createURI("john@email.com"));

        markLogicDatasetGraph
                .add(newgraph, NodeFactory.createURI("Joe"), NodeFactory.createURI("fname"), NodeFactory.createURI("Joefname"));
        markLogicDatasetGraph
                .add(newgraph, NodeFactory.createURI("Joe"), NodeFactory.createURI("lname"), NodeFactory.createURI("Joelname"));
        markLogicDatasetGraph.add(newgraph, NodeFactory.createURI("Joe"), NodeFactory.createURI("homeTel"),
                NodeFactory.createURI("222222222D"));
        markLogicDatasetGraph.add(newgraph, NodeFactory.createURI("Joe"), NodeFactory.createURI("email"),
                NodeFactory.createURI("joe@email.com"));

        markLogicDatasetGraph.add(newgraph, NodeFactory.createURI("jerry"), NodeFactory.createURI("fname"),
                NodeFactory.createURI("jerryfname"));
        markLogicDatasetGraph.add(newgraph, NodeFactory.createURI("jerry"), NodeFactory.createURI("lname"),
                NodeFactory.createURI("jerrylname"));
        markLogicDatasetGraph.add(newgraph, NodeFactory.createURI("jerry"), NodeFactory.createURI("homeTel"),
                NodeFactory.createURI("333333333D"));
        markLogicDatasetGraph.add(newgraph, NodeFactory.createURI("jerry"), NodeFactory.createURI("email"),
                NodeFactory.createURI("jerry@email.com"));

        String query1 = "CONSTRUCT{ ?person <homeTel> ?o .}  FROM <http://marklogic.com/graph1> WHERE {"
                + "  ?person <homeTel> ?o .  ?person <fname> ?firstname .} ";
        QuerySolutionMap binding = new QuerySolutionMap();
        binding.add("firstname", ResourceFactory.createResource("Joefname"));

        QueryExecution queryExec = QueryExecutionFactory.create(query1, dataSet, binding);
        Model results = queryExec.execConstruct();
        assertTrue(results.getGraph().size() == 1);
        assertTrue(results.getGraph().contains(Node.ANY, Node.ANY, NodeFactory.createURI("222222222D")));
grechaw commented 9 years ago

Hi @kkanthet I'm actually going to try to convince you that you should change your test and we need to push this off.

What's happening here is that the notion of BASE has different defaults for CRUD and SPARQL query.

When you insert, NodeFactory.createURI() is making relative URIs, but no base is set. This inserted into MarkLogic as a bare string (not an absolute URI).

On query, there's a default base. It is set to some ridiculous string having to do with the project location. So if you do nothing with BASE, then relative URIs in queries resolve to a different string. This is the regression, but actually it fixes BASE in query. so above is resoved to file://home/cgreer/path/to/project/homeTel which obviously won't match anything.

The solution would be to avoid relative URIs. People do generally avoid relative URIs in practice, as issues with BASE are common. A better fix for 1.0.2 would be to figure out what the default BASE should be for both CRUD and query, and make them the same.

Do you agree with the notion of modifying the tests to use full URIS (either :thisForm or http://this) in this particular case? And opening a new bug to deal with the bad default BASE for CRUD?

xquery commented 9 years ago

To add Jena (and Sesame) apply rules differently in different scenarios, for example if uploading a turtle file that defines base throughout ... no attempt is made to rewrite those BASE.

I also observe that in the REST API we do no BASE fixup when we upload a graph with relative elements (to set BASE to file name uri).

I think this needs to cook a little while and agree with Charles conclusions on this.

kkanthet commented 9 years ago

Updating test with Full URI works, Can we override the default base in query by default if we don't use one? I will create a new issue to fix base URI for crud for 1.0.2

grechaw commented 9 years ago

Yes -- QueryExecutionFactory.create(String queryString) is how we've been doing it mostly, but you can also do this:

Query q = QueryFactory.create(queryString, BASEURI) QueryExecutionFactory.create(q)