1
@prefix userS: <http://example.org/2017/6/user_schema#> .
@prefix user: <http://example.org/2017/6/user#> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .

user:account_62eb31ea-e665-49ec-9675-4282ced149da
    userS:uniqueId <urn:uuid:62eb31ea-e665-49ec-9675-4282ced149da> ;
    rdf:type
        foaf:OnlineAccount ,
        userS:Entity ;
    foaf:accountName 'foo' ;
    foaf:accountServiceHomepage <http://example.com/myaccount>
.

user:user_62eb31ea-e665-49ec-9675-4282ced149da
    rdf:type
        foaf:Person ,
        userS:Administrator ,
        userS:User ;
    foaf:holdsAccount user:account_62eb31ea-e665-49ec-9675-4282ced149da ;
    foaf:mbox <mailto:foo@example.com> ;
    # some meaningless BNODE example just for demonstration purposes
    # that should also be deleted
    user:xxx [ user:a user:b ] 
.

What I try to accomplish

  • find the account by user:uniqueId
    • delete all it's triples
  • find the resources that references the account by foaf:holdsAccount <urn:uuid:62eb31ea-e665-49ec-9675-4282ced149da>
    • delete all their triples as well
  • also delete all triples that are related by BNODEs (if any)

What I came up with

PREFIX userS: <http://example.org/2017/6/user_schema#>
PREFIX user: <http://example.org/2017/6/user#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>

WITH <http://bewellup.org/2017/6/product/bwu_product_user>
DELETE { 
  ?s ?p ?o .
}  
WHERE {  
  BIND (<urn:uuid:62eb31ea-e665-49ec-9675-4282ced149da> as ?accountId)
  {
    ?s rdf:type 
        foaf:OnlineAccount ;
        userS:uniqueId ?accountId .
    ?s ?p ?o .
  }
  UNION {
    ?account rdf:type 
        foaf:OnlineAccount ;
        userS:uniqueId ?accountId .
    ?s foaf:holdsAccount ?account .
    ?s ?p ?o .
  }
}

Is there a more concise or efficient way to delete all the created triples?

How do I also get the triples linked by BNODEs deleted?

Stanislav Kralin
  • 11,070
  • 4
  • 35
  • 58
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • 1
    If this are just directly connected blank nodes it's possible with something like `?o ?p1 ?o1` in the `DELETE` part and in both `UNION` parts: `OPTIONAL{FILTER(isBlank(?o)) ?o ?p1 ?o1}` but for nested or transitively connected triples it's more difficult resp. expensive. – UninformedUser Aug 21 '17 at 09:48
  • @AKSW thanks. Yes, I want all triples transitively connected by blank nodes be deleted as well. – Günter Zöchbauer Aug 21 '17 at 09:49
  • 1
    I've nothing to test here, but does this work? `OPTIONAL{FILTER(isBlank(?o)) ?o (:|!:)* ?s_del . ?s_del ?p_del ?o_del. ` in the `UNION` parts and `?s_del p_del ?o_del` to the `DELETE` part. Note, even if this works it doesn't consider incoming triples on the path – UninformedUser Aug 21 '17 at 10:29
  • @AKSW Thanks, I don't have time to try it just now, but I'll report back ASAP. You didn't mention anything about the delete statement I posted in my question yet. Does this mean using `UNION` as I did to delete related triples (independent of the BNODE problem) the right approach? – Günter Zöchbauer Aug 21 '17 at 10:37
  • 1
    Just to understand, you want to delete 1) the triples regarding the account as well as 2) the triples regarding the user? Then, it's perfect since you have to match two different structures. Now that I'm thinking about the data in general, ( indeed I'm not aware of the data), but what about a user having multiple accounts? I guess this isn't possible, right? – UninformedUser Aug 21 '17 at 10:51
  • @AKSW a user having multiple accounts might be relevant for the future, but not right now. The described example is what I expect I will need in many cases and I want to get this right before taking the next steps, and then in case extend to more complicated scenarios. – Günter Zöchbauer Aug 21 '17 at 11:07
  • "if this works it doesn't consider incoming triples on the path". Incoming triples also shouldn't matter for my use case. – Günter Zöchbauer Aug 21 '17 at 11:10
  • 1
    Ok, then my approach should work for now. At least I tested it on my local triple store and a `CONSTRUCT` query returns all the relevant triples - also the transitively connected once that I introduced for testing purpose. HTH – UninformedUser Aug 21 '17 at 11:18
  • Thanks a lot. That seems to work just fine. A `?` and `}` were missing. I posted the full query as answer. You can just copy it to your answer, then I'll delete mine. Some explanation about what `(:|!:)*` is about would be great. – Günter Zöchbauer Aug 21 '17 at 11:21
  • 1
    `(:|!:)` is a kind of wildcard, see e. g. [this answer](https://stackoverflow.com/a/26707541/7879193). Probably `(a|!a)*` is more clear :-). I'll delete this comment if @AKSW posts his answer. – Stanislav Kralin Aug 22 '17 at 07:00
  • Please add it as an answer, so that I can delete my temporary one. – Günter Zöchbauer Aug 22 '17 at 15:27

1 Answers1

1
PREFIX userS: <http://bewellup.org/2017/6/product/bwu_user_schema#>
PREFIX user: <http://bewellup.org/2017/6/product/bwu_product_user#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>

WITH <http://bewellup.org/2017/6/product/bwu_product_user>
DELETE { 
  ?s ?p ?o .
  ?s_del ?p_del ?o_del .
}
WHERE {  
  BIND (<urn:uuid:62eb31ea-e665-49ec-9675-4282ced149da> as ?accountId)
  {
    ?s rdf:type 
        foaf:OnlineAccount ;
        userS:uniqueId ?accountId .
    ?s ?p ?o .
     OPTIONAL{FILTER(isBlank(?o)) ?o (:|!:)* ?s_del . ?s_del ?p_del ?o_del. }
  }
  UNION {
    ?account rdf:type 
        foaf:OnlineAccount ;
        userS:uniqueId ?accountId .
    ?s foaf:holdsAccount ?account .
    ?s ?p ?o .
    OPTIONAL{FILTER(isBlank(?o)) ?o (:|!:)* ?s_del . ?s_del ?p_del ?o_del.}
  }
}
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567