How to find Objects that have the same Subject and Predicate


#1

I have a few quads like this one where the subject and predicate are the same:

<395c02bb-152c-11e8-b5f3-843a4b0f5a10> -- <schema:openingHoursSpecification> -> <395c03ce-152c-11e8-b5f3-843a4b0f5a10>
<395c02bb-152c-11e8-b5f3-843a4b0f5a10> -- <schema:openingHoursSpecification> -> <395c0445-152c-11e8-b5f3-843a4b0f5a10>

How do I find the all the Objects of those quads? What I am trying to do is delete all the quads that their Subject is those Objects (in my case I am trying to delete all the hours of operation related quads - slots, schema:open, schema:close, and schema:dayofweek)

Here is my entire db:

<395998f5-152c-11e8-b5f3-843a4b0f5a10> -- <rdf:type> -> <Admin>
<395998f5-152c-11e8-b5f3-843a4b0f5a10> -- <name> -> "Josh"
<395998f5-152c-11e8-b5f3-843a4b0f5a10> -- <email> -> "josh_f@gmail.com"
<395998f5-152c-11e8-b5f3-843a4b0f5a10> -- <hashed_password> -> "435iue8uou9eu"
<395c02bb-152c-11e8-b5f3-843a4b0f5a10> -- <rdf:type> -> <Clinic>
<395c02bb-152c-11e8-b5f3-843a4b0f5a10> -- <name> -> "Heal Now"
<395c02bb-152c-11e8-b5f3-843a4b0f5a10> -- <address> -> "3234 Rot Road, Singapore"
<395c02bb-152c-11e8-b5f3-843a4b0f5a10> -- <createdBy> -> <395998f5-152c-11e8-b5f3-843a4b0f5a10>
<395c02bb-152c-11e8-b5f3-843a4b0f5a10> -- <officeTel> -> "65 6100 0939"
<395c03ce-152c-11e8-b5f3-843a4b0f5a10> -- <rdf:type> -> <schema:OpeningHoursSpecification>
<395c03ce-152c-11e8-b5f3-843a4b0f5a10> -- <schema:dayOfWeek> -> <mon>
<395c03ce-152c-11e8-b5f3-843a4b0f5a10> -- <slot> -> "1"^^<schema:Integer>
<395c03ce-152c-11e8-b5f3-843a4b0f5a10> -- <schema:opens> -> "08:00"
<395c03ce-152c-11e8-b5f3-843a4b0f5a10> -- <schema:closes> -> "12:00"
<395c02bb-152c-11e8-b5f3-843a4b0f5a10> -- <schema:openingHoursSpecification> -> <395c03ce-152c-11e8-b5f3-843a4b0f5a10>
<395c0445-152c-11e8-b5f3-843a4b0f5a10> -- <rdf:type> -> <schema:OpeningHoursSpecification>
<395c0445-152c-11e8-b5f3-843a4b0f5a10> -- <schema:dayOfWeek> -> <mon>
<395c0445-152c-11e8-b5f3-843a4b0f5a10> -- <slot> -> "2"^^<schema:Integer>
<395c0445-152c-11e8-b5f3-843a4b0f5a10> -- <schema:opens> -> "13:00"
<395c0445-152c-11e8-b5f3-843a4b0f5a10> -- <schema:closes> -> "15:30"
<395c02bb-152c-11e8-b5f3-843a4b0f5a10> -- <schema:openingHoursSpecification> -> <395c0445-152c-11e8-b5f3-843a4b0f5a10>
<395c04d0-152c-11e8-b5f3-843a4b0f5a10> -- <rdf:type> -> <schema:OpeningHoursSpecification>
<395c04d0-152c-11e8-b5f3-843a4b0f5a10> -- <schema:dayOfWeek> -> <mon>
<395c04d0-152c-11e8-b5f3-843a4b0f5a10> -- <slot> -> "3"^^<schema:Integer>
<395c04d0-152c-11e8-b5f3-843a4b0f5a10> -- <schema:opens> -> "16:00"
<395c04d0-152c-11e8-b5f3-843a4b0f5a10> -- <schema:closes> -> "19:00"
<395c02bb-152c-11e8-b5f3-843a4b0f5a10> -- <schema:openingHoursSpecification> -> <395c04d0-152c-11e8-b5f3-843a4b0f5a10>
<395c0522-152c-11e8-b5f3-843a4b0f5a10> -- <rdf:type> -> <schema:OpeningHoursSpecification>
<395c0522-152c-11e8-b5f3-843a4b0f5a10> -- <schema:dayOfWeek> -> <tue>
<395c0522-152c-11e8-b5f3-843a4b0f5a10> -- <slot> -> "1"^^<schema:Integer>
<395c0522-152c-11e8-b5f3-843a4b0f5a10> -- <schema:opens> -> "09:00"
<395c0522-152c-11e8-b5f3-843a4b0f5a10> -- <schema:closes> -> "12:30"
<395c02bb-152c-11e8-b5f3-843a4b0f5a10> -- <schema:openingHoursSpecification> -> <395c0522-152c-11e8-b5f3-843a4b0f5a10>
<395c056c-152c-11e8-b5f3-843a4b0f5a10> -- <rdf:type> -> <schema:OpeningHoursSpecification>
<395c056c-152c-11e8-b5f3-843a4b0f5a10> -- <schema:dayOfWeek> -> <tue>
<395c056c-152c-11e8-b5f3-843a4b0f5a10> -- <slot> -> "2"^^<schema:Integer>
<395c056c-152c-11e8-b5f3-843a4b0f5a10> -- <schema:opens> -> "13:00"
<395c056c-152c-11e8-b5f3-843a4b0f5a10> -- <schema:closes> -> "18:00"
<395c02bb-152c-11e8-b5f3-843a4b0f5a10> -- <schema:openingHoursSpecification> -> <395c056c-152c-11e8-b5f3-843a4b0f5a10>

Thanks!


#2

You can open a delete stream to your database and “copy” the quads you want to delete from iterator to the stream.

Something like this should do the job:

func RemovePrefix(qs *graph.Handle, s, p quad.Value) error {
	// open delete stream
	del := graph.NewRemover(h)
	defer del.Close()

	// query for quads with specific constraints
	qu := shape.Quads{
		{Dir: quad.Subject, Values: shape.Lookup{s}},
		{Dir: quad.Predicate, Values: shape.Lookup{p}},
	}

	// build an iterator for query
	it := shape.BuiltIterator(h, qu)
	defer it.Close()

	// stream quads from that iterator
	r := graph.NewResultReader(s.qs, it)

	// send all quads from iterator to delete stream
	total, err := quad.Copy(del, r)
	r.Close()
	if err != nil {
		return err
	}
	// don't forget to flush - it closes the transaction
	if err := del.Flush(); err != nil {
		return err
	}
	if total == 0 {
		return graph.ErrNodeNotExists
	}
	return nil
}

#3

Interesting! Thank you.