View Source

\\ (!) In order to run these examples, make sure that the default corpus is populated as described in the [Installation guide].

h2. Creating combined \{semantic + keyword\} queries

The combined \{semantic + keyword\} query is actually a new enhancement to the existing {{SemanticQuery}}. It consists of a semantic part and a keyword part. By binding semantic variables, they are connected to specific document fields, where the search is performed. Therefore, you can now search not only for documents matching specific entities, but also extend this query and find documents in which these entities appear together with other entities or terms.

_Example: To find all People whose name starts with "John" and at the same time are included in documents with the word "fraud" in their titles and Organization in their bodies._

The element that joins these two searches is the document binding condition, that the searched locations should be contained in the "body" field of the document.

{code:java}// ----------------------------------------------------------------------------------
// create a combined {semantic + keyword} query
// ----------------------------------------------------------------------------------
SemanticQuery query = new SemanticQuery();
query.setReturnLabels(true);
// ----------------------------------------------------------------------------------

// add variable PERS of class Person
query.addRequestedVar("PERS");
query.setClass("PERS", WKBConstants.CLASS_PERSON);
// ----------------------------------------------------------------------------------

// restrict person to start with 'john'
query.addNameRestriction("PERS", CompareStyleConstants.COMPARE_STYLE_STARTS_WITH, "john");
// ----------------------------------------------------------------------------------

// add variable ORG of class Organization
query.setClass("ORG", WKBConstants.CLASS_ORGANIZATION);
// ----------------------------------------------------------------------------------

// bind 'PERS' and 'ORG' variables to the 'body' field of the document
// these bindings make the connection between the semantic and keyword parts
query.addBoundVar("PERS");
query.addBoundVar("ORG");
// ----------------------------------------------------------------------------------

// look for documents that contain 'fraud' in the title
query.setKeywordRestriction(new AtomExpr("fraud", "title"));
// ----------------------------------------------------------------------------------
{code}

You can easily have two or more semantic variables bound, so you can search for co-existing entities. However, the current implementation restricts you to have these variables related in the preceding semantic part (i.e. you must ensure that the semantic part is canonical). The code below will give you all pairs of organizations and locations that have the "locatedIn" relation, are in the same documents, and the document set is restricted by some keywords.
{code:java}SemanticQuery semQ = new SemanticQuery();
// ----------------------------------------------------------------------------------
semQ.setClass("ORG", WKBConstants.CLASS_ORGANIZATION);
semQ.addRequestedVar("ORG");
semQ.setClass("LOC", WKBConstants.CLASS_LOCATION);
semQ.addRequestedVar("LOC");
// ----------------------------------------------------------------------------------
semQ.addPatternRestriction("ORG", WKBConstants.PROPERTY_LOCATED_IN, "LOC");
// ----------------------------------------------------------------------------------
semQ.addKeywordRestriction("body", ...);
semQ.addKeywordRestriction("TITLE", ...);
// ----------------------------------------------------------------------------------
semQ.addBoundVar("ORG");
semQ.addBoundVar("LOC");
// ----------------------------------------------------
semQ.setMaxResultLength(10);
{code}


h2. Browsing results

When you execute such a complex query, you can request both entities and documents. As you can see in the code below, this cannot be done simultaneously. You can use the different methods of the API:

{code:java}// ----------------------------------------------------------------------------------
// get and process results from a combined query
// ----------------------------------------------------------------------------------


// ----------------------------------------------------------------------------------
// getting entities
// ----------------------------------------------------------------------------------
SemanticQueryResult resEntities = apiQuery.getEntities(semQ);
System.out.println("Entities : " + resEntities.size());

System.out.println("[ Combined Query Entities (begin) ]");
for (SemanticQueryResultRow row : resEntities) {
System.out.println(" - ---------------------------");
String tmpRow = "";
for (int i = 1; i < row.size(); i += 2) {
tmpRow += "\t|\t" + row.get(i);
}
tmpRow += "\t|\t";
System.out.println(" - " + tmpRow);
}
System.out.println(" - ---------------------------");
System.out.println("[ Combined Query Entities (end) ]");
// ----------------------------------------------------------------------------------


// ----------------------------------------------------------------------------------
// getting documents
// ----------------------------------------------------------------------------------
DocumentQueryResult resDocuments = apiQuery.getDocumentIds(semQ)
.getReferringDocuments();
System.out.println("Documents : " + resDocuments.size());

System.out.println("[ Combined Query Docs (begin) ]");
for (DocumentQueryResultRow row : resDocuments) {
KIMDocument doc = apiDR.loadDocument(row.getDocumentId());
System.out.println(" - " + doc.getFeatures().get("TITLE"));
}
System.out.println("[ Combined Query Docs (end) ]");
// ----------------------------------------------------------------------------------
{code}

The Result Flags in the entity and document results indicate if some limits were reached during the execution of the query and if the results were truncated. These limits have default values but you can also change them at runtime. For more details about each of them and how to change their values at the beginning, please see the [Configuring the Semantic Repository] and [Configuring the Document Repository] sections.