Skip to content

Commit

Permalink
implementation search method
Browse files Browse the repository at this point in the history
Issue imixs#554
  • Loading branch information
rsoika committed Sep 1, 2019
1 parent 9040f47 commit bfc867e
Show file tree
Hide file tree
Showing 3 changed files with 250 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@

import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.imixs.workflow.ItemCollection;
import org.imixs.workflow.WorkflowKernel;
import org.imixs.workflow.engine.DocumentService;
import org.imixs.workflow.engine.EventLogService;
import org.imixs.workflow.engine.SetupEvent;
Expand Down Expand Up @@ -477,6 +478,9 @@ protected String buildAddDoc(List<ItemCollection> documents) {
addFieldValuesToUpdateRequest(xmlContent, document, aFieldname);
}

// add $uniqueid not analyzed
addFieldValuesToUpdateRequest(xmlContent, document, WorkflowKernel.UNIQUEID);

xmlContent.append("</doc>");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
package org.imixs.workflow.engine.solr;

import java.io.StringReader;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;
Expand All @@ -48,7 +50,6 @@
import org.imixs.workflow.engine.index.SchemaService;
import org.imixs.workflow.engine.index.SearchService;
import org.imixs.workflow.exceptions.QueryException;
import org.imixs.workflow.util.JSONParser;

/**
* This session ejb provides a service to search the solr index.
Expand Down Expand Up @@ -153,12 +154,22 @@ public List<ItemCollection> search(String searchTerm, int pageSize, int pageInde
logger.finest("......Result = " + result);

if (result != null && !result.isEmpty()) {
List<ItemCollection> documentStubs = parseJSONQueyResult(result);
// now we extract the docs and build ItemCollections from it....
List<ItemCollection> documentStubs = parseQueryResult(result);
if (loadStubs) {
workitems.addAll(documentStubs);
} else {
// load workitems
for (ItemCollection stub: documentStubs) {
ItemCollection document=documentService.load(stub.getUniqueID());
if (document!=null) {
workitems.add(document);
}
}
}

}

logger.fine("...search result computed in " + (System.currentTimeMillis() - ltime) + " ms - loadStubs="
logger.info("...search result computed in " + (System.currentTimeMillis() - ltime) + " ms - loadStubs="
+ loadStubs);

return workitems;
Expand All @@ -167,39 +178,230 @@ public List<ItemCollection> search(String searchTerm, int pageSize, int pageInde
/**
* This method extracts the docs from a Solr JSON query result
*
* @param json - solr query response (JSON)
* @param json
* - solr query response (JSON)
* @return List of ItemCollection objects
*/
protected List<ItemCollection> parseJSONQueyResult(String json) {
List<ItemCollection> result= new ArrayList<ItemCollection>();
String response = JSONParser.getKey("response", json);
String docs = JSONParser.getKey("docs", response);

// now we go through the json docs structure and build ItemCollections ......


logger.info("docs=" + docs);
JsonParser parser = Json.createParser(new StringReader(docs));

protected List<ItemCollection> parseQueryResult(String json) {
long l = System.currentTimeMillis();
List<ItemCollection> result = new ArrayList<ItemCollection>();
JsonParser parser = Json.createParser(new StringReader(json));
Event event = null;
while (true) {

try {
event = parser.next(); // START_OBJECT
if (event == null) {
return null;
break;
}

if (event.name().equals(Event.KEY_NAME.toString())) {
String jsonkey = parser.getString();
break;
if ("docs".equals(jsonkey)) {
event = parser.next(); // docs array
if (event.name().equals(Event.START_ARRAY.toString())) {
event = parser.next();
while (event.name().equals(Event.START_OBJECT.toString())) {
// a single doc..

logger.finest("......parse doc....");
ItemCollection itemCol = parseDoc(parser);
// now take the values
result.add(itemCol);
event = parser.next();
}


if (event.name().equals(Event.END_ARRAY.toString())) {
break;

}

}

}

}
} catch (NoSuchElementException e) {
return null;
break;
}
}

logger.info("******* total parsing time " + (System.currentTimeMillis() - l) + "ms");
return result;
}

/**
* Builds a ItemCollection from a json doc strcuture
*
* @param parser
* @return
*/
private ItemCollection parseDoc(JsonParser parser) {
ItemCollection document = new ItemCollection();
Event event = null;
event = parser.next(); // a single doc..
while (event.name().equals(Event.KEY_NAME.toString())) {
String itemName = parser.getString();
logger.finest("......found item " + itemName);
List<?> itemValue = parseItem(parser);
// convert itemName and value....
itemName=adaptItemName(itemName);
document.replaceItemValue(itemName, itemValue);
event = parser.next();
}

return document;
}

/**
* parses a single item value
*
* @param parser
* @return
*/
private List<Object> parseItem(JsonParser parser) {
SimpleDateFormat dateformat = new SimpleDateFormat("yyyyMMddHHmmss");
List<Object> result = new ArrayList<Object>();
Event event = null;
while (true) {
event = parser.next(); // a single doc..
if (event.name().equals(Event.START_ARRAY.toString())) {

while (true) {
event = parser.next(); // a single doc..
if (event.name().equals(Event.VALUE_STRING.toString())) {
// just return the next json object here

result.add(convertLuceneValue(parser.getString(),dateformat));
}
if (event.name().equals(Event.VALUE_NUMBER.toString())) {
// just return the next json object here
//result.add(parser.getBigDecimal());

result.add(convertLuceneValue(parser.getString(),dateformat));
}
if (event.name().equals(Event.VALUE_TRUE.toString())) {
// just return the next json object here
result.add(true);
}
if (event.name().equals(Event.VALUE_FALSE.toString())) {
// just return the next json object here
result.add(false);
}
if (event.name().equals(Event.END_ARRAY.toString())) {
break;
}
}

}

if (event.name().equals(Event.VALUE_STRING.toString())) {
// single value!
result.add(parser.getString());
}
if (event.name().equals(Event.VALUE_NUMBER.toString())) {
// just return the next json object here
result.add(parser.getBigDecimal());
}
if (event.name().equals(Event.VALUE_TRUE.toString())) {
// just return the next json object here
result.add(true);
}
if (event.name().equals(Event.VALUE_FALSE.toString())) {
// just return the next json object here
result.add(false);
}

break;
}

return result;
}

/**
* This
* @param stringValue
* @return
*/
private Object convertLuceneValue(String stringValue, SimpleDateFormat luceneDateformat) {
Object objectValue = null;
// check for numbers....
if (isNumeric(stringValue)) {
// is date?
if (stringValue.length() == 14 && !stringValue.contains(".")) {
try {
objectValue = luceneDateformat.parse(stringValue);
} catch (java.text.ParseException e) {
// no date!
}
}
// lets see if it is a number..?
if (objectValue == null) {
try {
Number number = NumberFormat.getInstance().parse(stringValue);
objectValue = number;
} catch (java.text.ParseException e) {
// no number - should not happen
}
}
}
if (objectValue == null) {
objectValue = stringValue;
}
return objectValue;
}


/**
* Helper method to check for numbers.
*
* @see https://stackoverflow.com/questions/1102891/how-to-check-if-a-string-is-numeric-in-java
* @param str
* @return
*/
private static boolean isNumeric(String str) {
boolean dot = false;
if (str == null || str.isEmpty()) {
return false;
}
for (char c : str.toCharArray()) {
if (c == '.' && dot == false) {
dot = true; // first dot!
continue;
}
if (c < '0' || c > '9') {
return false;
}
}
return true;

}

/**
* This method adapts an item name to the corresponding Imixs Item name
*
* @param itemName
* @return
*/
private String adaptItemName(String itemName) {

String[] from = { "_uniqueid", "_modified", "_created" };
String[] to = { "$uniqueid", "$modified", "$created" };

int max = from.length;
for (int i = 0; i < max; i++) {
if (from[i].equalsIgnoreCase(itemName)) {
itemName = to[i];
break;
}
}



return itemName;
}

/**
* Returns the total hits for a given search term from the lucene index. The
* method did not load any data. The provided search term will we extended with
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package org.imixs.workflow.engine.solr;

import java.io.StringReader;
import java.util.List;
import java.util.logging.Logger;

import javax.json.Json;
import javax.json.stream.JsonParser;

import org.imixs.workflow.ItemCollection;
import org.imixs.workflow.exceptions.ModelException;
import org.imixs.workflow.exceptions.PluginException;
Expand All @@ -19,14 +23,18 @@
*/
public class TestParseSolrJSONResult {

@SuppressWarnings("unused")

private final static Logger logger = Logger.getLogger(TestParseSolrJSONResult.class.getName());

SolrSearchService solrSearchService=null;

@Before
public void setUp() throws PluginException, ModelException {

// init parser just to measure time correctly

JsonParser parser = Json.createParser(new StringReader("{}"));

solrSearchService=new SolrSearchService();
}

Expand All @@ -37,7 +45,7 @@ public void setUp() throws PluginException, ModelException {
*/
@Test
public void testParseResult() {

List<ItemCollection> result=null;
String testString = "{\n" +
" \"responseHeader\":{\n" +
" \"status\":0,\n" +
Expand All @@ -62,12 +70,22 @@ public void testParseResult() {




// List<ItemCollection> result=solrSearchService.parseJSONQueyResult(testString);
//
//
// Assert.assertTrue(result.size()==2);
result=solrSearchService.parseQueryResult(testString);
Assert.assertEquals(2,result.size());

ItemCollection document=null;

document=result.get(0);
Assert.assertEquals("model", document.getItemValueString("type"));
Assert.assertEquals("3a182d18-33d9-4951-8970-d9eaf9d337ff", document.getUniqueID());
Assert.assertEquals(1567278977000l, document.getItemValueDate("$modified").getTime());
Assert.assertEquals(1567278977000l, document.getItemValueDate("$created").getTime());

document=result.get(1);
Assert.assertEquals("adminp", document.getItemValueString("type"));
Assert.assertEquals("60825929-4d7d-4346-9333-afd7dbfca457", document.getUniqueID());
Assert.assertEquals(1567278978000l, document.getItemValueDate("$created").getTime());

}

}

0 comments on commit bfc867e

Please sign in to comment.