As described in the Knowledge Graph article, nodes may be directly connected to each other by edges.
For example, a Company node may have edges out to Person nodes of type employs to indicate that they work there -
(Note: Not shown is that that will probably be employedBy edges going back from Person to Company and writtenBy edges from Document to Person)
You may want to connect Company nodes to Document nodes, so that it is possible to see all of the documents that are owned by people working for particular companies or you might even want to filter document search results based upon which company their author was employed by.
If this is a one-off "ad hoc" query that you want to run (eg. "find me all of the documents written by people working at Acme Corp.") then you might want to run code in the Shell such as this:
.StartAt("Organization", "Acme Corp.")
But if you want connections from company to document to be incorporated into the graph (which is necessary if you want to use them as search filters / facets) then you need edges to exist from the company nodes leading to the document nodes.
One way to do this would be for you to import your data through a custom data connector that would be responsible for creating edges from company-to-person and person-to-document and from company-to-document but this would essentially be duplicating edge information in the graph and would require additional work in the connector (or would require additional work to write the custom connector in the first place, if you have been importing your data up this point from CSV, Microsoft Graph, GitHub, or any of the other supported data sources).
Another approach is to define Inferred Edges for the graph. This is a way to create "virtual edges" between nodes, determined by edges that exist between intermediary nodes. To continue the example above, you could configured an inferred edge type that would automatically connect any company nodes to document nodes if the company nodes have person nodes that are connected to both the company and the documents in question.
On the image above, the "owns" connection between the company and the document is an inferred edge.
To specify rules for defining inferred edges, click on the Curiosity menu button and then Settings and then Data and then Inferencing Rules.
Note that there will already be some default rules visible here that all Curiosity applications are created with. The third one in the screenshot above is similar to the example in this article;
- When a PDF is imported into Curiosity, a File node (known behind the scenes as being of the _FileEntry node type) is created and it will be linked to the User that imported it (if they imported it as a private upload) via an _OwnedBy edge.
- The _OwnedBy edge is used to only show results to Users in searches for content that they have access to (see Limiting node access to particular Users or Teams for more details about this).
- The Curiosity application will have started examining the PDF as soon as it is uploaded to extract text content to facilitate searching (potentially using OCR to interpret scanned images of text, if configured to do so by following the instructions in one of the OCR articles under Advanced Settings).
- The result of the Curiosity analysis is that internal nodes are added to the graph that contain the extracted text (and other information, such as on what page that text appeared in the PDF). These nodes will be connected to the File node by _OwnedBy edges.
- When a search is performed, Curiosity will look at the text content of these internal nodes but only if the current User has permissions to access them, which is easy for it to determine as there will be an inferred _OwnedBy edge connecting the internal nodes to the User that imported the PDF.
So in the scenario detailed above, whenever there is a path in the graph like this:
File OwnedBy Something OwnedBy SomethingElse
Then an inferred edge will appear in the graph that looks like this:
File OwnedBy SomethingElse
To return to the example that we started with, we want to take paths like this
Company employs Something authorOf SomethingElse
And we want inferred edges to appear in the graph like this:
Company owns SomethingElse
(Note: We know that the Something node type will always be of type Person in this example because any edge that is of type employs and that comes from a company must lead to a person in order to make sense, likewise the node type SomethingElse will always be Document because any edge that is of type authorOf and that comes from a person must lead to a document)
To do this, note that the columns in the rules list have headings Node Type, First Edge, Second Edge, Results in and Recursive.
For our use case, the starting Node Type is Company, the First Edge is employs, the Second Edge is authorOf and the Results in (which is an edge type) is owns.
Use the drop down boxes at the bottom of the form to set your options and click the + button.
Note that inferred edges (as with all edges) are one way. So the presence of an inferred edge that joins Acme Corp. to Important Document does not necessarily mean that there will be an inferred return edge that joins Important Document back to Acme Corp. As such, it is recommended that you also add a rule for return inferred edges as well. In this example, that would be a rule that looks for paths like this:
Document writtenBy Something employedBy SomethingElse
In order that inferred edges exist like this:
Document ownedBy SomethingElse
To create that return edge rule, the starting Node Type would be Document, the First Edge would be writtenBy, the Second Edge would be employedBy and the Results in would be ownedBy.
Using inferred edges to filter search results
If you want to use these inferred edges to set up "Related Facet" options to filter search results (eg. if a User was searching within Documents and wanted to be able to see only those by Acme Corp.) then this is almost as easy as configuring up Related Facet options for directly-connected nodes. See the Related Filters for inferred connections section in the Configuring Search Filters for information on how to do this.