I have modeled the following object properties in my Ontology:
Harbor locatedIn some City
City locatedIn some Country
I want the inferential engine to infer that a
Harbor locatedIn some Country
Moreover, I want him to infer that a
City hasHarbor(another object property) some Harbor
Thank you for your help.
First: to infer that: Harbor subClassOf locatedIn some Country
You should define locatedIn as Transitive (you can use protege GUI)
Second: The reasoner won't create hasHarbor property on its own. It should be defined first, and you can assert it as inverseOf locatedIn (you can use protege GUI).
Related
I am currently doing some manual analysis of the data in neo4j data base gathered with the BloodHound tool.
When doing manual queries I can see a 'Base' type node that is not introduced in the BloodHound documentation.
MATCH (n) RETURN distinct labels(n) returns:
["Base", "User"]
["Base", "Group"]
["Base"]
["Base", "Computer"]
["Base", "Domain"]
["Base", "GPO"]
["Base", "OU"]
When checking properties of the Base nodes they seem to take properties of other node types.
My question is what exactly are those 'Base' nodes?
I tried to find this info in BloodHound and Neo4j documentation but with no success.
You can create nodes with multiple labels in the graph database. I am not familiar with the bloodhound but it might be adding an extra label to nodes called "Base" to distinguish its data from the existing ones or There might be a good chance that there are several higher categories under which lower categories fall e.g., "User", "Group", "Computer"... fall under "Base". By doing MATCH (n:Base).... you are matching all the nodes under "Base" category.
The Base label, as previously suggested, has nothing to do with Neo internals.
While the documentation for the tool does not address the base label, the source code provides some hints. I recommend looking at these:
https://github.com/BloodHoundAD/BloodHound/blob/08a3469c523b4066e8e5248bdbcfb985acab5117/src/js/newingestion.js
https://github.com/BloodHoundAD/BloodHound/blob/08a3469c523b4066e8e5248bdbcfb985acab5117/src/js/newingestion.js
https://github.com/BloodHoundAD/BloodHound/blob/67cf1dee4f6c8d77a71b3eceb49b4040a5eb9550/src/components/Graph.jsx
Base appears to be a convenience grouping. It is common to have multiple labels for any node. For example, you can have UserAccount nodes (~Base) that have also other labels that define the role of any specific UserAccount.
I'm using pizza ontology, and there is this object property called hasCountryOfOrigin. This object property doesn't have specific domain and range, probably because the domain can be pizza or pizzaTopping. For other object properties, for example hasBase, I can find where it's used with ontology.getAxioms(AxiomType.OBJECT_PROPERTY_DOMAIN) because it has domain and range. So how can I find where hasCountryOfOrigin is used using OWLAPI?
You can use:
Searcher.values(ontology.axioms(AxiomType.OBJECT_PROPERTY_ASSERTION), property);
This will provide all assertions that have property as the property, e.g., all axioms of the form subject property value.
You can then iterate over the axioms and check the types for the subject and object to infer possible domains and ranges from usage.
(Note that these do not force the property to have these classes as domains or ranges; it's just that those classes would not surprise a reasoner or a human looking at the ontology, if they were to be asserted to be domains or ranges of the property.)
is there any way individual (instance) connect to class with object property? For example, individual in this case is module name: Web Programming. Object property : isClassified. Class: Network.
I've tried to define Web Programming as class, and it works because the domain and range are both classes. Same goes if I define both Web Programming & Network as individuals, it works. If the domain is a class and the range is individual, it still works. But what if the domain is individual and the range is class? Is there any way I can connect it with object property: isClassifiedIn?
Protégé is an OWL 2 DL editor (since version 4). In OWL 2 DL, an individual cannot be a class, and an object property must relate individuals to individuals only. So what you want cannot be expressed in the way you formulate it. However, you could do two things:
use an annotation property instead of an object property. This may not be ideal because an OWL DL reasoner must ignore annotation properties in the reasoning process. They are just that: annotations, similar to comments in a programming code.
relate the individual to another individual that has the same name as the class. Let me give details about this.
In OWL 2 DL, although it is not possible for individuals to be classes, it is possible for individual names to be class names at the same time. For instance, one can say (in Turtle syntax):
ex:Module a owl:Class .
ex:Network a owl:Class, owl:Thing .
ex:isClassified a owl:ObjectProperty .
ex:webProgramming a ex:Module;
ex:isClassified ex:Network .
Note that ex:webProgramming here is not related to a class. It is related to an individual of type owl:Thing. This individual has nothing to do, a priori, with the class named ex:Network, although it has the same name. This is called "punning" in the OWL 2 specification.
There is a third way: change your knowledge model such that you do not encounter this problem. I do not know your ontology, but it could be hinting at an antipattern that you should avoid.
You have to use "value".
Write your own expression using the class expression editor.
Select the class Than write:
"property" value "individual"
I'm totally new to Neo4j and I'm testing it in these days.
One issue I have with it is how to correctly implement a relationship which involves 3 different nodes using Spring Data. Suppose, for example, that I have 3 #NodeEntitys: User, Tag and TaggableObject.
As you can argue, a User can add a Tag to a TaggableObject; I model this operation with a #RelationshipEntity TaggingOperation.
However, I can't find a simple way to glue the 3 entities inside the relationship. I mean, the obvious choice is to set #StartNode User tagger and #EndNode TaggedObject taggedObject; but how can I also add the Tag to the relationship?
This is called a "hyperedge", I believe, and it's not something that Neo4j supports directly. You can create an additional node to support it, tough. So you could have a TagEvent node with a schema like so:
(:User)-[:PERFORMED]->(:TagEvent)
(:Tag)<-[:USED]-(:TagEvent)
(:TagObject)<-[:TAGGED]-(:TagEvent)
Another alternative is to store a foreign key as a property on a relationship or a node. Obviously that's not very graphy, but if you just need it for reference that might not be a bad solution. Just remember to not use the internal Neo4j ID as in future versions that may not be dependable. You should create your own ID for this purpose.
I'm playing around with neo4j, and I was wondering, is it common to have a type property on nodes that specify what type of Node it is? I've tried searching for this practice, and I've seen some people use name for a purpose like this, but I was wondering if it was considered a good practice or if indexes would be the more practical method?
An example would be a "User" node, which would have type: user, this way if the index was bad, I would be able to do an all-node scan and look for types of user.
Labels have been added to neo4j 2.0. They fix this problem.
You can create nodes with labels:
CREATE (me:American {name: "Emil"}) RETURN me;
You can match on labels:
MATCH (n:American)
WHERE n.name = 'Emil'
RETURN n
You can set any number of labels on a node:
MATCH (n)
WHERE n.name='Emil'
SET n :Swedish:Bossman
RETURN n
You can delete any number of labels on a node:
MATCH (n { name: 'Emil' })
REMOVE n:Swedish
Etc...
True, it does depend on your use case.
If you add a type property and then wish to find all users, then you're in potential trouble as you've got to examine that property on every node to get to the users. In that case, the index would probably do better- but not in cases where you need to query for all users with conditions and relations not available in the index (unless of course, your index is the source of the "start").
If you have graphs like mine, where a relation type implies two different node types like A-(knows)-(B) and A or B can be a User or a Customer, then it doesn't work.
So your use case is really important- it's easy to model graphs generically, but important to "tune" it as per your usage pattern.
IMHO you shouldn't have to put a type property on the node. Instead, a common way to reference all nodes of a specific "type" is to connect all user nodes to a node called "Users" maybe. That way starting at the Users node, you can very easily find all user nodes. The "Users" node itself can be indexed so you can find it easily, or it can be connected to the reference node.
I think it's really up to you. Some people like indexed type attributes, but I find that they're mostly useful when you have other indexed attributes to narrow down the number of index hits (search for all users over age 21, for example).
That said, as #Luanne points out, most of us try to solve the problem in-graph first. Another way to do that (and the more natural way, in my opinion) is to use the relationship type to infer a practical node type, i.e. "A - (knows) -> B", so A must be a user or some other thing that can "know", and B must be another user, a topic, or some other object that can "be known".
For client APIs, modeling the element type as a property makes it easy to instantiate the right domain object in your client-side code so I always include a type property on each node/vertex.
The "type" var name is commonly used for this, but in some languages like Python, "type" is a reserved word so I use "element_type" in Bulbs ( http://bulbflow.com/quickstart/#models ).
This is not needed for edges/relationships because they already contain a type (the label) -- note that Neo4j also uses the keyword "type" instead of label for relationships.
I'd say it's common practice. As an example, this is exactly how Spring Data Neo4j knows of which entity type a certain node is. Each node has "type" property that contains the qualified class name of the entity. These properties are automatically indexed in the "types" index, thus nodes can be looked up really fast. You could implement your use case exactly like this.
Labels have recently been added to Neo4j 2.0 ( http://docs.neo4j.org/chunked/milestone/graphdb-neo4j-labels.html ). They are still under development at the moment, but they address this exact problem.