Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Temp #444

Open
wants to merge 4 commits into
base: dev
Choose a base branch
from
Open

Temp #444

wants to merge 4 commits into from

Conversation

hmottestad
Copy link
Contributor

No description provided.

@hmottestad hmottestad changed the base branch from master to dev January 22, 2024 20:00
Comment on lines +39 to +83
public void setupRepo() throws IOException {
Path root = tempDir.newFolder().toPath();
ClassLoader loader = getClass().getClassLoader();
String filename = "2018_complete.nt";

Path hdtstore = root.resolve("hdt-store");
Path locationNative = root.resolve("native");

Files.createDirectories(hdtstore);
Files.createDirectories(locationNative);

String indexName = "index.hdt";

HDTOptions options = HDTOptions.of(
// disable the default index (to use the custom indexes)
HDTOptionsKeys.BITMAPTRIPLES_INDEX_NO_FOQ, true,
// set the custom indexes we want
HDTOptionsKeys.BITMAPTRIPLES_INDEX_OTHERS, "sop,ops,osp,pso,pos");


try (HDT hdt = HDTManager.generateHDT(new Iterator<>() {
@Override
public boolean hasNext() {
return false;
}

@Override
public TripleString next() {
return null;
}
}, Utility.EXAMPLE_NAMESPACE, options, null)) {
hdt.saveToHDT(hdtstore.resolve(indexName).toAbsolutePath().toString(), null);
} catch (Error | RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}

repository = CompiledSail.compiler().withEndpointFiles(new EndpointFiles(locationNative, hdtstore, indexName))
.compileToSparqlRepository();
try (InputStream is = new BufferedInputStream(Objects.requireNonNull(loader.getResourceAsStream(filename),
filename + " doesn't exist"))) {
repository.loadFile(is, filename);
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ate47 I'm using this code to set up a repo with the file from #413

The query statistics seems to always be returning 0. Do you know why?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you detail this a bit more. I loaded the dataset and I was querying one triple pattern and I see that the cardinality is non zero:
Screenshot 2024-01-22 at 22 52 51

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try adding a break point on that line and then debugging the TempTest test() I added.

Copy link
Contributor Author

@hmottestad hmottestad Jan 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't forget to add the file with the data to this path: qendpoint-store/src/test/resources/2018_complete.nt

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a race condition because a merge was triggered in the middle of the file loading

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you know how I can wait for the merge to complete?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw. In my PR eclipse-rdf4j/rdf4j#4879 I managed to get the QueryJoinOptimizer to work better when the statistics are inaccurately returning 0.0 by adding 5.0 to the cost of all operations and also penalising cartesian joins more heavily.

@@ -0,0 +1,123 @@
Distinct (resultSizeActual=12, totalTimeActual=9.8s, selfTimeActual=0.048ms)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I managed to manually optimize the query and it runs in about 10 seconds on my laptop.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what did you change?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, you mean, you still have the problem that the query planner is not woriking and you tried to reorder the triple patterns by hand only?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. I managed to reorder the query by hand.

Comment on lines +124 to +125
# This line should be above the FILTER and BIND, but doing so causes the QueryJoinOptimizer to not optimize the query for some unknown reason
?resultnotice epo:refersToRole ?buyerrole .
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@D063520 @ate47

This line should be above the FILTER and BIND. When I put it above then the QueryJoinOptimizer doesn't manage to optimize the query at all. When I move it back down again like I've done now then it does end up triggering the QueryJoinOptimizer seemingly correctly, but it only seems to check the cardinality of this single statement pattern here and when it does it gets 0.0 as the cardinality.

If you run the test you should see the following printed:

Cardinality for StatementPattern    Var (name=resultnotice)    Var (name=_const_6aa9a9c_uri, value=http://data.europa.eu/a4g/ontology#refersToRole, anonymous)    Var (name=buyerrole)  is 0.0 (HDT: 0.0, Native: 0.0)

Copy link
Contributor Author

@hmottestad hmottestad Jan 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had a look at the QueryJoinOptimizer code and it doesn't seem to recurse down into the query tree. Essentially it will recurse down to the first Join and then optimize the join arguments that are either instance of Join or LeftJoin or StatementPattern. Removing the inner sub-select from the query "fixes" the QueryJoinOptimizer.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fixed the QueryJoinOptimizer eclipse-rdf4j/rdf4j#4879

@hmottestad
Copy link
Contributor Author

hmottestad commented Jan 29, 2024

graphviz

@hmottestad
Copy link
Contributor Author

Distinct (resultSizeActual=9, totalTimeActual=6.0s, selfTimeActual=0.028ms)
   Projection (resultSizeActual=9, totalTimeActual=6.0s, selfTimeActual=0.046ms)
   ├── ProjectionElemList
   │     ProjectionElem "countryID"
   │     ProjectionElem "year"
   │     ProjectionElem "amountLots"
   │     ProjectionElem "numSingleBidders"
   └── Extension (resultSizeActual=9, totalTimeActual=6.0s, selfTimeActual=0.027ms)
         Group (countryID, year) (resultSizeActual=9, totalTimeActual=6.0s, selfTimeActual=34.8ms)
            Join (HashJoinIteration) (resultSizeActual=32.7K, totalTimeActual=6.0s, selfTimeActual=55.5ms)
            ╠══ Extension (resultSizeActual=69.8K, totalTimeActual=4.6s, selfTimeActual=241ms) [left]
            ║  ├── Join (JoinIterator) (resultSizeActual=69.8K, totalTimeActual=4.3s, selfTimeActual=1.1s)
            ║  │  ╠══ StatementPattern [index: SPO]  (costEstimate=1.25, resultSizeEstimate=0, resultSizeActual=106.3K, totalTimeActual=185ms, selfTimeActual=185ms) [left]
            ║  │  ║     s: Var (name=stat)
            ║  │  ║     p: Var (name=_const_25686184_uri, value=http://data.europa.eu/a4g/ontology#concernsSubmissionsForLot, anonymous)
            ║  │  ║     o: Var (name=lot)
            ║  │  ╚══ Join (JoinIterator) (resultSizeActual=69.8K, totalTimeActual=3.0s, selfTimeActual=842ms) [right]
            ║  │     ├── StatementPattern [index: SPO]  (costEstimate=1.00, resultSizeEstimate=0, resultSizeActual=106.3K, totalTimeActual=82.6ms, selfTimeActual=82.6ms) [left]
            ║  │     │     s: Var (name=stat)
            ║  │     │     p: Var (name=_const_f5e5585a_uri, value=http://www.w3.org/1999/02/22-rdf-syntax-ns#type, anonymous)
            ║  │     │     o: Var (name=_const_ea79e75_uri, value=http://data.europa.eu/a4g/ontology#SubmissionStatisticalInformation, anonymous)
            ║  │     └── Join (JoinIterator) (resultSizeActual=69.8K, totalTimeActual=2.1s, selfTimeActual=78.7ms) [right]
            ║  │        ╠══ StatementPattern [index: SPO]  (costEstimate=2.24, resultSizeEstimate=0, resultSizeActual=96.8K, totalTimeActual=82.3ms, selfTimeActual=82.3ms) [left]
            ║  │        ║     s: Var (name=stat)
            ║  │        ║     p: Var (name=_const_98c73a3c_uri, value=http://data.europa.eu/a4g/ontology#hasReceivedTenders, anonymous)
            ║  │        ║     o: Var (name=bidders)
            ║  │        ╚══ Join (JoinIterator) (resultSizeActual=69.8K, totalTimeActual=2.0s, selfTimeActual=80.8ms) [right]
            ║  │           ├── StatementPattern [index: Unknown]  (costEstimate=98, resultSizeEstimate=152.1K, resultSizeActual=96.8K, totalTimeActual=35.6ms, selfTimeActual=35.6ms) [left]
            ║  │           │     s: Var (name=proc)
            ║  │           │     p: Var (name=_const_9c3f1eec_uri, value=http://data.europa.eu/a4g/ontology#hasProcurementScopeDividedIntoLot, anonymous)
            ║  │           │     o: Var (name=lot)
            ║  │           └── Join (JoinIterator) (resultSizeActual=69.8K, totalTimeActual=1.8s, selfTimeActual=504ms) [right]
            ║  │              ╠══ StatementPattern [index: SPO]  (costEstimate=1.00, resultSizeEstimate=152.1K, resultSizeActual=96.8K, totalTimeActual=17.0ms, selfTimeActual=17.0ms) [left]
            ║  │              ║     s: Var (name=proc)
            ║  │              ║     p: Var (name=_const_f5e5585a_uri, value=http://www.w3.org/1999/02/22-rdf-syntax-ns#type, anonymous)
            ║  │              ║     o: Var (name=_const_be18ee7b_uri, value=http://data.europa.eu/a4g/ontology#Procedure, anonymous)
            ║  │              ╚══ Join (JoinIterator) (resultSizeActual=69.8K, totalTimeActual=1.3s, selfTimeActual=319ms) [right]
            ║  │                 ├── StatementPattern [index: SPO]  (costEstimate=75, resultSizeEstimate=90.9K, resultSizeActual=96.6K, totalTimeActual=85.6ms, selfTimeActual=85.6ms) [left]
            ║  │                 │     s: Var (name=resultnotice)
            ║  │                 │     p: Var (name=_const_183bd06d_uri, value=http://data.europa.eu/a4g/ontology#refersToProcedure, anonymous)
            ║  │                 │     o: Var (name=proc)
            ║  │                 └── Join (JoinIterator) (resultSizeActual=69.8K, totalTimeActual=913ms, selfTimeActual=287ms) [right]
            ║  │                    ╠══ StatementPattern [index: SPO]  (costEstimate=1.00, resultSizeEstimate=90.9K, resultSizeActual=96.6K, totalTimeActual=40.2ms, selfTimeActual=40.2ms) [left]
            ║  │                    ║     s: Var (name=resultnotice)
            ║  │                    ║     p: Var (name=_const_f5e5585a_uri, value=http://www.w3.org/1999/02/22-rdf-syntax-ns#type, anonymous)
            ║  │                    ║     o: Var (name=_const_77e914ad_uri, value=http://data.europa.eu/a4g/ontology#ResultNotice, anonymous)
            ║  │                    ╚══ Join (JoinIterator) (resultSizeActual=69.8K, totalTimeActual=586ms, selfTimeActual=266ms) [right]
            ║  │                       ├── StatementPattern [index: SPO]  (costEstimate=281, resultSizeEstimate=79.1K, resultSizeActual=87.5K, totalTimeActual=38.4ms, selfTimeActual=38.4ms) [left]
            ║  │                       │     s: Var (name=resultnotice)
            ║  │                       │     p: Var (name=_const_1b0b00ca_uri, value=http://data.europa.eu/a4g/ontology#hasDispatchDate, anonymous)
            ║  │                       │     o: Var (name=ddate)
            ║  │                       └── Join (JoinIterator) (resultSizeActual=69.8K, totalTimeActual=281ms, selfTimeActual=72.9ms) [right]
            ║  │                          ╠══ StatementPattern [index: SPO]  (costEstimate=301, resultSizeEstimate=90.9K, resultSizeActual=87.5K, totalTimeActual=49.9ms, selfTimeActual=49.9ms) [left]
            ║  │                          ║     s: Var (name=resultnotice)
            ║  │                          ║     p: Var (name=_const_6aa9a9c_uri, value=http://data.europa.eu/a4g/ontology#refersToRole, anonymous)
            ║  │                          ║     o: Var (name=buyerrole)
            ║  │                          ╚══ Filter (resultSizeActual=69.8K, totalTimeActual=158ms, selfTimeActual=146ms) [right]
            ║  │                             ├── Compare (!=)
            ║  │                             │     Var (name=p)
            ║  │                             │     ValueConstant (value=http://publications.europa.eu/resource/authority/procurement-procedure-type/neg-wo-call)
            ║  │                             └── StatementPattern [index: SPO]  (costEstimate=382, resultSizeEstimate=145.9K, resultSizeActual=84.4K, totalTimeActual=11.9ms, selfTimeActual=11.9ms)
            ║  │                                   s: Var (name=proc)
            ║  │                                   p: Var (name=_const_9c756f6b_uri, value=http://data.europa.eu/a4g/ontology#hasProcedureType, anonymous)
            ║  │                                   o: Var (name=p)
            ║  └── ExtensionElem (year)
            ║        FunctionCall (http://www.w3.org/2005/xpath-functions#year-from-dateTime)
            ║           FunctionCall (http://www.w3.org/2001/XMLSchema#dateTime)
            ║              Var (name=ddate)
            ╚══ Distinct (new scope) (resultSizeActual=61.6K, totalTimeActual=1.4s, selfTimeActual=184ms) [right]
                  Projection (resultSizeActual=1.0M, totalTimeActual=1.2s, selfTimeActual=107ms)
                  ╠══ ProjectionElemList
                  ║     ProjectionElem "buyerrole"
                  ║     ProjectionElem "countryID"
                  ╚══ Join (JoinIterator) (resultSizeActual=1.0M, totalTimeActual=1.1s, selfTimeActual=87.3ms)
                     ├── StatementPattern [index: SPO]  (costEstimate=1.25, resultSizeEstimate=0, resultSizeActual=4.1K, totalTimeActual=8.76ms, selfTimeActual=8.76ms) [left]
                     │     s: Var (name=org)
                     │     p: Var (name=_const_beb18915_uri, value=https://www.w3.org/ns/legal#registeredAddress, anonymous)
                     │     o: Var (name=orgaddress)
                     └── Join (JoinIterator) (resultSizeActual=1.0M, totalTimeActual=977ms, selfTimeActual=85.4ms) [right]
                        ╠══ StatementPattern [index: SPO]  (costEstimate=1.12, resultSizeEstimate=0, resultSizeActual=4.1K, totalTimeActual=4.38ms, selfTimeActual=4.38ms) [left]
                        ║     s: Var (name=orgaddress)
                        ║     p: Var (name=_const_2f7de0e1_uri, value=http://data.europa.eu/a4g/ontology#hasCountryCode, anonymous)
                        ║     o: Var (name=countrycode)
                        ╚══ Join (JoinIterator) (resultSizeActual=1.0M, totalTimeActual=888ms, selfTimeActual=94.6ms) [right]
                           ├── StatementPattern [index: SPO]  (costEstimate=2.24, resultSizeEstimate=0, resultSizeActual=4.1K, totalTimeActual=3.46ms, selfTimeActual=3.46ms) [left]
                           │     s: Var (name=countrycode)
                           │     p: Var (name=_const_a825a5f4_uri, value=http://purl.org/dc/elements/1.1/identifier, anonymous)
                           │     o: Var (name=countryID)
                           └── Join (JoinIterator) (resultSizeActual=1.0M, totalTimeActual=790ms, selfTimeActual=460ms) [right]
                              ╠══ Filter (resultSizeActual=70.1K, totalTimeActual=36.0ms, selfTimeActual=11.8ms) [left]
                              ║  ├── Compare (!=)
                              ║  │     Var (name=buytype)
                              ║  │     ValueConstant (value=http://publications.europa.eu/resource/authority/buyer-legal-type/eu-int-org)
                              ║  └── StatementPattern [index: SPO]  (costEstimate=2.24, resultSizeEstimate=0, resultSizeActual=74.3K, totalTimeActual=24.2ms, selfTimeActual=24.2ms)
                              ║        s: Var (name=org)
                              ║        p: Var (name=_const_1abd8d4b_uri, value=http://data.europa.eu/a4g/ontology#hasBuyerType, anonymous)
                              ║        o: Var (name=buytype)
                              ╚══ StatementPattern [index: Unknown]  (costEstimate=351, resultSizeEstimate=123.2K, resultSizeActual=1.0M, totalTimeActual=294ms, selfTimeActual=294ms) [right]
                                    s: Var (name=buyerrole)
                                    p: Var (name=_const_beb855c2_uri, value=http://data.europa.eu/a4g/ontology#playedBy, anonymous)
                                    o: Var (name=org)
            GroupElem (amountLots)
               Count (Distinct)
                  Var (name=lot)
            GroupElem (numSingleBidders)
               Sum
                  If
                     Compare (=)
                        Var (name=bidders)
                        ValueConstant (value="1"^^<http://www.w3.org/2001/XMLSchema#integer>)
                     ValueConstant (value="1"^^<http://www.w3.org/2001/XMLSchema#integer>)
                     ValueConstant (value="0"^^<http://www.w3.org/2001/XMLSchema#integer>)
         ExtensionElem (amountLots)
            Count (Distinct)
               Var (name=lot)
         ExtensionElem (numSingleBidders)
            Sum
               If
                  Compare (=)
                     Var (name=bidders)
                     ValueConstant (value="1"^^<http://www.w3.org/2001/XMLSchema#integer>)
                  ValueConstant (value="1"^^<http://www.w3.org/2001/XMLSchema#integer>)
                  ValueConstant (value="0"^^<http://www.w3.org/2001/XMLSchema#integer>)

@hmottestad
Copy link
Contributor Author

hmottestad commented Jan 29, 2024

Cardinality for StatementPattern    Var (name=proc)    Var (name=_const_f5e5585a_uri, value=http://www.w3.org/1999/02/22-rdf-syntax-ns#type, anonymous)    Var (name=_const_be18ee7b_uri, value=http://data.europa.eu/a4g/ontology#Procedure, anonymous)  is 
152106.0 (HDT: 76053.0, Native: 76053.0)

Cardinality for StatementPattern    Var (name=proc)    Var (name=_const_9c756f6b_uri, value=http://data.europa.eu/a4g/ontology#hasProcedureType, anonymous)    Var (name=p)  is 
145876.0 (HDT: 72938.0, Native: 72938.0)

Cardinality for StatementPattern    Var (name=proc)    Var (name=_const_9c3f1eec_uri, value=http://data.europa.eu/a4g/ontology#hasProcurementScopeDividedIntoLot, anonymous)    Var (name=lot)  is 
152106.0 (HDT: 76053.0, Native: 76053.0)

Cardinality for StatementPattern    Var (name=stat)    Var (name=_const_f5e5585a_uri, value=http://www.w3.org/1999/02/22-rdf-syntax-ns#type, anonymous)    Var (name=_const_ea79e75_uri, value=http://data.europa.eu/a4g/ontology#SubmissionStatisticalInformation, anonymous)  is 
0.0 (HDT: 0.0, Native: 0.0)

Cardinality for StatementPattern    Var (name=stat)    Var (name=_const_25686184_uri, value=http://data.europa.eu/a4g/ontology#concernsSubmissionsForLot, anonymous)    Var (name=lot)  is 
0.0 (HDT: 0.0, Native: 0.0)

Cardinality for StatementPattern    Var (name=stat)    Var (name=_const_98c73a3c_uri, value=http://data.europa.eu/a4g/ontology#hasReceivedTenders, anonymous)    Var (name=bidders)  is 
0.0 (HDT: 0.0, Native: 0.0)

Cardinality for StatementPattern    Var (name=resultnotice)    Var (name=_const_f5e5585a_uri, value=http://www.w3.org/1999/02/22-rdf-syntax-ns#type, anonymous)    Var (name=_const_77e914ad_uri, value=http://data.europa.eu/a4g/ontology#ResultNotice, anonymous)  is 
90886.0 (HDT: 45443.0, Native: 45443.0)

Cardinality for StatementPattern    Var (name=resultnotice)    Var (name=_const_183bd06d_uri, value=http://data.europa.eu/a4g/ontology#refersToProcedure, anonymous)    Var (name=proc)  is 
90888.0 (HDT: 45444.0, Native: 45444.0)

Cardinality for StatementPattern    Var (name=resultnotice)    Var (name=_const_1b0b00ca_uri, value=http://data.europa.eu/a4g/ontology#hasDispatchDate, anonymous)    Var (name=ddate)  is 
79072.0 (HDT: 39536.0, Native: 39536.0)

Cardinality for StatementPattern    Var (name=resultnotice)    Var (name=_const_6aa9a9c_uri, value=http://data.europa.eu/a4g/ontology#refersToRole, anonymous)    Var (name=buyerrole)  is 
90886.0 (HDT: 45443.0, Native: 45443.0)

Cardinality for StatementPattern    Var (name=buyerrole)    Var (name=_const_beb855c2_uri, value=http://data.europa.eu/a4g/ontology#playedBy, anonymous)    Var (name=org)  is 
123222.0 (HDT: 61611.0, Native: 61611.0)

Cardinality for StatementPattern    Var (name=org)    Var (name=_const_beb18915_uri, value=https://www.w3.org/ns/legal#registeredAddress, anonymous)    Var (name=orgaddress)  is 
0.0 (HDT: 0.0, Native: 0.0)

Cardinality for StatementPattern    Var (name=orgaddress)    Var (name=_const_2f7de0e1_uri, value=http://data.europa.eu/a4g/ontology#hasCountryCode, anonymous)    Var (name=countrycode)  is 
0.0 (HDT: 0.0, Native: 0.0)

Cardinality for StatementPattern    Var (name=countrycode)    Var (name=_const_a825a5f4_uri, value=http://purl.org/dc/elements/1.1/identifier, anonymous)    Var (name=countryID)  is 
0.0 (HDT: 0.0, Native: 0.0)

Cardinality for StatementPattern    Var (name=org)    Var (name=_const_1abd8d4b_uri, value=http://data.europa.eu/a4g/ontology#hasBuyerType, anonymous)    Var (name=buytype)  is 
0.0 (HDT: 0.0, Native: 0.0)

@hmottestad
Copy link
Contributor Author

@ate47 @D063520

I've merged the fix for the QueryJoinOptimizer and it's available from the snapshot repo. The query still needs a slight modification. RDF4J does not optimise the location of the BIND clause, so it is unable to move the ?resultnotice epo:refersToRole ?buyerrole . above the BIND clause. By moving the BIND clause below this line the query runs in 6 seconds on my laptop.

My original theory that RDF4J can't optimise sub-selects was wrong. Queries with a single sub-select can be optimised, but not if the non-sub-select parts contain a BIND clause. They can also not be optimised if there is more than one sub-select. With the changes to the QueryJoinOptimizer it can now optimise both of these types of queries.

The three comments above this one contain the query plan and the statistics. I managed to get my code to wait for the HDT merging to complete, but as you can see there are still quite a few places where the statistics are returning 0.0. I haven't looked further into why this is the case.

Here is the final query that I ended up with:

PREFIX epo: <http://data.europa.eu/a4g/ontology#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX legal: <https://www.w3.org/ns/legal#>
PREFIX dcterms: <http://purl.org/dc/terms#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX dc: <http://purl.org/dc/elements/1.1/>

SELECT DISTINCT ?countryID ?year (COUNT(DISTINCT ?lot) AS ?amountLots) (SUM(if(?bidders = 1, 1, 0)) AS ?numSingleBidders) WHERE {

        ?proc a epo:Procedure .
        ?proc epo:hasProcedureType ?p .
        FILTER ( ?p != <http://publications.europa.eu/resource/authority/procurement-procedure-type/neg-wo-call>)
        ?proc epo:hasProcurementScopeDividedIntoLot ?lot .

        ?stat a epo:SubmissionStatisticalInformation .
        ?stat epo:concernsSubmissionsForLot ?lot .
        ?stat epo:hasReceivedTenders ?bidders .

        ?resultnotice a epo:ResultNotice .
        ?resultnotice epo:refersToProcedure ?proc .
        ?resultnotice epo:hasDispatchDate ?ddate .

        ?resultnotice epo:refersToRole ?buyerrole .

     	BIND(year(xsd:dateTime(?ddate)) AS ?year) .

        {
          SELECT DISTINCT ?buyerrole ?countryID WHERE {
            ?buyerrole epo:playedBy ?org .
            ?org legal:registeredAddress ?orgaddress .
            ?orgaddress epo:hasCountryCode ?countrycode  .
            ?countrycode dc:identifier ?countryID .

            ?org epo:hasBuyerType ?buytype .
            FILTER (?buytype != <http://publications.europa.eu/resource/authority/buyer-legal-type/eu-int-org> )
          }
        }

} GROUP BY ?countryID ?year

@hmottestad
Copy link
Contributor Author

@D063520 Would you like to me comment on the original discussion page to outline my findings and the solution?

@D063520
Copy link
Contributor

D063520 commented Feb 11, 2024

yes please!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants