holodex / app

http://holodex.enspiral.com
GNU Affero General Public License v3.0
24 stars 1 forks source link

Semantic queries #62

Closed simontegg closed 9 years ago

simontegg commented 9 years ago

I'm currently implementing very simple semantic queries in the ui:

this might get more complex: [Groups to which] [Person] [belongs]

I collect research on how to do this here

simontegg commented 9 years ago

http://www.cobase.cs.ucla.edu/tech-docs/ucla-990003.pdf http://research.microsoft.com/apps/pubs/default.aspx?id=172303 http://livingknowledge.europarchive.org/images/publications/NLDB09.pdf https://docs.google.com/viewer?url=https%3A%2F%2Fgate.ac.uk%2Fsale%2Ftalks%2Fgate-course-july09%2Fquestio.ppt http://services.gate.ac.uk/freya/ https://gate.ac.uk/sale/eswc08/clone-ql/clone-ql.pdf

ahdinosaur commented 9 years ago

i reckon we should start with

[type(s)] who are [triple(s)]

so

[People] who are [members of Enspiral Craftworks]

or

[People and Groups] who are [members of Enspiral Services] and [members of Enspiral Craftworks]

and such. thoughts on this approach @simontegg ?

simontegg commented 9 years ago

something like that, yes.

The original motivation for this was to avoid using 'members'. Early user testing of my development branch demonstrated that people interpreted the 'members of' language in its vernacular sense in Enspiral i.e. 'the special category of person with stakeholding in a group' not the generic 'person/group in group' as intended.

Its impossible to confuse 'People in', 'groups in' 'people that belong to', so that is what I went with. My sense is that the language should be more verb and preposition -based rather than noun-based (== roles) to avoid this confusion.

ahdinosaur commented 9 years ago

yeah, the confusion around the term members and the focus on verb and preposition-based words makes sense.

so

[People] who [belong to Craftworks]

or

[People and Groups] who [belong to Enspiral Services] and [belong to Enspiral Craftworks]

?

simontegg commented 9 years ago

I've also been using a separated verb-predicate-tag [belongs to] to toggle the links on and off. This creates cases (in fact the default case) where the [roleType] is active but the [belongs to] is inactive and the graph displays the members floating around the context agent.

[role: member, type: Person] [Group] ==

[People in] [Group]

simontegg commented 9 years ago

The thinking is that the [belongs to] relationship is superfluous for simple cases, (show me people in this group) and complicates the graph when other links are added. But we do want it for more complex queries:

[People] in and [Groups] that [belong to] [Enspiral Services] [and] [People] who [belong to] [Craftworks]

Graph shows Services in the center, service members floating around, teams connected to services, and CW members connected to CW

simontegg commented 9 years ago

or perhaps more clearly:

[People in] [Enspiral Services] and [Groups] that [belong to] [Enspiral Services] and [People] who [belong to] [Craftworks]

ahdinosaur commented 9 years ago

ah okay, i guess i didn't fully understand how the semantic query worked, i didn't realize '[People in] [Enspiral Services]' was semantically different from '[People] who [belong to] [Enspiral Services]'. i thought the query was solely for determining what subset of agents to show in the graph, then the selected roles and relationships determine what circles and arrows are shown between those agents. @simontegg how would you feel about doing it this way?

simontegg commented 9 years ago

Unifying [People in] [Enspiral Services] and '[People] who [belong to] [Enspiral Services] is certainly simpler. We could have [People in] be the standard then have a specific [belongs to Enspiral services] and a general [belongs to] trigger edges in the inset filters.

However, in user testing when the triple shows just [Enspiral Craftworks]: the expectation is that when [is steward of] tag is present will show the agents on both sides of that relationship.

ahdinosaur commented 9 years ago

We could have [People in] be the standard then have a specific [belongs to Enspiral services] and a general [belongs to] trigger edges in the inset filters.

i'd prefer the consistency of always using '[People] who [belong to Enspiral Services]' which follows the convention of '[type(s)] who [query triple(s)]' over having a special case, but it's whatever.

However, in user testing when the triple shows just [Enspiral Craftworks]: the expectation is that when [is steward of] tag is present will show the agents on both sides of that relationship.

so an example: the query is 'People who belong to Enspiral Craftworks' and the 'stewards' relationship tag is selected. would a user expect to see your stewards relationship as a member of Loomio? or do you mean something else?

simontegg commented 9 years ago

I mean with the triple fragment [Enspiral Craftworks] {no belong to, no people} only the contextAgent (CW) is displayed Then the user selects [is steward of] {in this case Ive used the role noun} the expectation is for this to add people in CW to the graph that participate in the stewardship relationship in the context of CW and draw this particular edge between them

simontegg commented 9 years ago

Logic notes WIP

[blank] graph is blank, filter dropdown loaded with all available agents

case: role and link tags removed leaving -> [Person] || [Group] graph shows person or group, filter -> (opposite side) roles and ingoing and outgoing links

Person default: [Groups] [that include] [**Person***] graph shows person and links to their groups, filter -> (opposite side) roles and ingoing and outgoing links

Groups default: has childgroups [Groups] [that belong to] [**Group***] graph shows group and links to their child groups, filter -> (opposite side) roles and ingoing and outgoing links

Groups default: does not have childgroups [People in] [**Group***] graph shows group and people members floating around, filter -> (opposite side) roles and ingoing and outgoing links

ahdinosaur commented 9 years ago

@simontegg i really like what you've done so far. :+1: i'm reading up on your links. i'll admit i'm having a bit of trouble understanding your code, which is totally fine as it's more important right now that it works, so i might start sketching out what a clean re-write might look like based on what we're learning from what you're doing, while i try to give any feedback or iterative improvements on what i do understand.

simontegg commented 9 years ago

Thanks yeah Im currently refactoring get-tag-data. I've refactored format-graph-data on the parent branch so that's manageable and works but it still has a way to go

simontegg commented 9 years ago

basic principles for triple filters (thinking outloud):

the subject is an 'agentType' + a 'Role' the predicate is a link, (companion to the subject's 'Role if present) (not properly modeled yet) the object is an Agent. (contextAgent)

object: show contextAgent alone

subject + object: show halo'd agents that play that role and are of that agentType floating around contextAgent

predicate + object: options: (a) impossible (removing subject also removes companion predicate, leaving object) (b) show all agents that have the link to the contextAgent with edges attached to the contextAgent (removing a tag adds agents to the graph ....hmmm)

subject + predicate + object show halo'd agents that play that role and are of that agentType attached to with edges contextAgent

ahdinosaur commented 9 years ago

another way of thinking (aloud):

a triple is [subject, predicate, object]. a query triple has variables in one or more places. triples can be stacked for more complex queries.

most basic query is [subject, var(predicate), var(object)], which means 'Anything that relates to subject'.

a type query is [var(subject), '@type', type], which combined with the previous triple query means 'Types that relate to subject'.

a query to find all agents that have a specific type of role: [[var(agent), 'hasRole', var(role)], [var(role), 'roleType', roleType]].

a query to find all agents that have a specific type of relationship with a specific other agent: [[otherAgent, 'hasRelationship', var(relationship)], [var(relationship), 'relationshipType', relationshipType], [var(agent), 'hasRelationship', var(relationship)]].

for the user interface, we should collapse these multi-triple role and relationship queries into a single component. or maybe we even massage the data into the triple store with alias triples, for example membership relationships create 'belongsTo' and 'includes' triples on the people and group objects respectively, so it's easier for everyone to query (and it seems to be more popular to have relation properties over relation objects).

simontegg commented 9 years ago
Filter: 
  AgentType: [AgentType]
  Role: boolean
  Link: boolean
  Agent || ContextAgent: [Agent] 

Member

 AgentType: 'Person'
 Role: true
 Link: true 
 Agent: CW: (true)
-> "[People who] [belong to] [CW]"

de-select [belong to] ->

 AgentType: 'Person'
 Role: true
 Link: false 
 Agent: CW
-> "[People in] [CW]"

Steward:

 AgentType: 'Person'
 Role: true
 Link: true 
 ContextAgent: CW: (true)
-> "[Stewards in CW]"
-> "[is steward of]"
AgentType: 'Person'
 Role: true
 Link: false 
 ContextAgent: CW: (true)
-> "[Stewards in CW]"
AgentType: 'Person'
 Role: false
 Link: true 
 ContextAgent: CW: (true)
-> "[is steward of]"