final Map<String, String[]> facetInfoMap)
throws Exception
{
json = jsonTemplateProcessor.substituteTemplates(json);
SenseiRequest req = new SenseiRequest();
JSONObject meta = json.optJSONObject("meta");
if (meta != null)
{
JSONArray array = meta.optJSONArray("select_list");
if (array != null)
{
List<String> list = new ArrayList<String>();
for (int i = 0; i < array.length(); ++i)
{
list.add(array.get(i).toString());
}
req.setSelectList(list);
}
}
// query
req.setQuery(new SenseiJSONQuery(json));
// paging params
int count = json.optInt(RequestConverter2.PAGING_SIZE, 10);
int offset = json.optInt(RequestConverter2.PAGING_FROM, 0);
req.setCount(count);
req.setOffset(offset);
// group by
JSONObject groupBy = json.optJSONObject("groupBy");
if (groupBy != null)
{
JSONArray columns = groupBy.optJSONArray("columns");
if (columns != null && columns.length() >= 1)
{
String[] groupByArray = new String[columns.length()];
for (int i=0; i<columns.length(); ++i)
groupByArray[i] = columns.getString(i);
req.setGroupBy(groupByArray);
}
req.setMaxPerGroup(groupBy.optInt("top", groupBy.optInt("count", 1)));
}
// distinct
JSONObject distinct = json.optJSONObject("distinct");
if (distinct != null)
{
JSONArray columns = distinct.optJSONArray("columns");
if (columns != null && columns.length() >= 1)
{
String[] distinctArray = new String[columns.length()];
for (int i=0; i<columns.length(); ++i)
distinctArray[i] = columns.getString(i);
if (distinctArray.length == 1 && req.getGroupBy() == null)
{
// rewrite to use group by
req.setGroupBy(distinctArray);
req.setMaxPerGroup(0);
}
else
{
req.setDistinct(distinctArray);
}
}
}
// selections
Object selections = json.opt(RequestConverter2.SELECTIONS);
if (selections == null)
{
// ignore
}
else if (selections instanceof JSONArray)
{
JSONArray selectionArray = (JSONArray)selections;
for(int i=0; i<selectionArray.length(); i++)
{
JSONObject selItem = selectionArray.optJSONObject(i);
if(selItem != null){
Iterator<String> keyIter = selItem.keys();
while(keyIter.hasNext()){
String type = keyIter.next();
JSONObject jsonSel = selItem.optJSONObject(type);
if(jsonSel != null){
addSelection(type, jsonSel, req, facetInfoMap);
}
}
}
}
}
else if (selections instanceof JSONObject)
{
JSONObject selectionObject = (JSONObject)selections;
Iterator<String> keyIter = selectionObject.keys();
while (keyIter.hasNext())
{
String type = keyIter.next();
JSONObject jsonSel = selectionObject.optJSONObject(type);
if (jsonSel != null)
addSelection(type, jsonSel, req, facetInfoMap);
}
}
//map reduce
JSONObject mapReduceJson = json.optJSONObject(RequestConverter2.MAP_REDUCE);
if (mapReduceJson != null) {
String key = mapReduceJson.getString(MAP_REDUCE_FUNCTION);
SenseiMapReduce senseiMapReduce = MapReduceRegistry.get(key);
senseiMapReduce.init(mapReduceJson.optJSONObject(MAP_REDUCE_PARAMETERS));
req.setMapReduceFunction(senseiMapReduce);
}
// facets
JSONObject facets = json.optJSONObject(RequestConverter2.FACETS);
if (facets!=null){
Iterator<String> keyIter = facets.keys();
while (keyIter.hasNext()){
String field = keyIter.next();
JSONObject facetObj = facets.getJSONObject(field);
if (facetObj!=null){
FacetSpec facetSpec = new FacetSpec();
facetSpec.setMaxCount(facetObj.optInt(RequestConverter2.FACETS_MAX, 10));
facetSpec.setMinHitCount(facetObj.optInt(RequestConverter2.FACETS_MINCOUNT, 1));
facetSpec.setExpandSelection(facetObj.optBoolean(RequestConverter2.FACETS_EXPAND, false));
String orderBy = facetObj.optString(RequestConverter2.FACETS_ORDER, RequestConverter2.FACETS_ORDER_HITS);
FacetSpec.FacetSortSpec facetOrder = FacetSpec.FacetSortSpec.OrderHitsDesc;
if (RequestConverter2.FACETS_ORDER_VAL.equals(orderBy)){
facetOrder = FacetSpec.FacetSortSpec.OrderValueAsc;
}
facetSpec.setProperties(createFacetProperties(facetObj));
facetSpec.setOrderBy(facetOrder);
req.setFacetSpec(field, facetSpec);
}
}
}
//facet init;
JSONObject facetInitParams = json.optJSONObject(RequestConverter2.FACETINIT);
if (facetInitParams != null)
{
Iterator<String> keyIter = facetInitParams.keys();
while (keyIter.hasNext())
{
// may have multiple facets;
String facetName = keyIter.next();
DefaultFacetHandlerInitializerParam param =
new DefaultFacetHandlerInitializerParam();
JSONObject jsonParams = facetInitParams.getJSONObject(facetName);
if (jsonParams != null && jsonParams.length() > 0)
{
Iterator<String> paramIter = jsonParams.keys();
while (paramIter.hasNext())
{
// each facet may have multiple parameters to be configured;
String paramName = paramIter.next();
JSONObject jsonParamValues = jsonParams.getJSONObject(paramName);
String type = jsonParamValues.optString(RequestConverter2.FACETINIT_TYPE, RequestConverter2.FACETINIT_TYPE_STRING);
JSONArray jsonValues = jsonParamValues.optJSONArray(RequestConverter2.FACETINIT_VALUES);
if (jsonValues == null)
{
// Accept scalar values here too. This is useful in
// supporting variable substitutions.
Object value = jsonParamValues.opt(RequestConverter2.FACETINIT_VALUES);
if (value != null)
{
jsonValues = new FastJSONArray().put(value);
}
}
if (jsonValues != null)
{
if (type.equals(RequestConverter2.FACETINIT_TYPE_INT))
param.putIntParam(paramName, convertJSONToIntArray(jsonValues));
else if (type.equals(RequestConverter2.FACETINIT_TYPE_STRING))
param.putStringParam(paramName, convertJSONToStringArray(jsonValues));
else if (type.equals(RequestConverter2.FACETINIT_TYPE_BOOLEAN))
param.putBooleanParam(paramName, convertJSONToBoolArray(jsonValues));
else if (type.equals(RequestConverter2.FACETINIT_TYPE_LONG))
param.putLongParam(paramName, convertJSONToLongArray(jsonValues));
else if (type.equals(RequestConverter2.FACETINIT_TYPE_BYTES))
param.putByteArrayParam(paramName, convertJSONToByteArray(jsonValues));
else if (type.equals(RequestConverter2.FACETINIT_TYPE_DOUBLE))
param.putDoubleParam(paramName, convertJSONToDoubleArray(jsonValues));
}
}
req.setFacetHandlerInitializerParam(facetName, param);
}
}
}
// sorts
JSONArray sortArray = json.optJSONArray(RequestConverter2.SORT);
if (sortArray!=null && sortArray.length()>0){
ArrayList<SortField> sortFieldList = new ArrayList<SortField>(sortArray.length());
for (int i=0;i<sortArray.length();++i){
Object obj = sortArray.opt(i);
if(obj instanceof JSONObject){
String field = (String) ((JSONObject)obj).keys().next();
if (field == null || field.length() == 0)
continue;
if (SORT_SCORE.equals(field) || SORT_RELEVANCE.equalsIgnoreCase(field))
{
sortFieldList.add(SortField.FIELD_SCORE);
continue;
}
String order = ((JSONObject)obj).optString(field);
boolean rev = false;
if(RequestConverter2.SORT_DESC.equals(order))
rev = true;
sortFieldList.add(new SortField(field,SortField.CUSTOM,rev));
continue;
}
else if (obj instanceof String){
if(SORT_SCORE.equals(obj)){
sortFieldList.add(SortField.FIELD_SCORE);
continue;
}
}
}
if (sortFieldList.size()>0){
req.setSort(sortFieldList.toArray(new SortField[sortFieldList.size()]));
}
}
// other
if (json.has(RequestConverter2.SCORE_MEANINGFUL_DIGITS))
req.setScoreMeaningfulDigits( json.getInt(RequestConverter2.SCORE_MEANINGFUL_DIGITS) );
boolean fetchStored = json.optBoolean(RequestConverter2.FETCH_STORED);
req.setFetchStoredFields(fetchStored);
boolean fetchStoredValue = json.optBoolean(RequestConverter2.FETCH_STORED_VALUE);
req.setFetchStoredValue(fetchStoredValue);
String[] termVectors = getStrings(json,RequestConverter2.TERM_VECTORS);
if (termVectors!=null && termVectors.length>0){
req.setTermVectorsToFetch(new HashSet<String>(Arrays.asList(termVectors)));
}
req.setPartitions(getIntSet(json, RequestConverter2.PARTITIONS,0));
req.setShowExplanation(json.optBoolean(RequestConverter2.EXPLAIN,false));
req.setTrace(json.optBoolean(RequestConverter2.TRACE,false));
String routeParam = json.optString(RequestConverter2.ROUTEPARAM,null);
req.setRouteParam(routeParam);
return req;
}