final IndexState state = getState(req, resp);
if (state == null)
return;
final IndexSearcher searcher = state.borrowSearcher(isStaleOk(req));
final String etag = state.getEtag();
final FastVectorHighlighter fvh = new FastVectorHighlighter(true, true);
final JSONArray result = new JSONArray();
try {
if (state.notModified(req)) {
resp.setStatus(304);
return;
}
for (final String queryString : getQueryStrings(req)) {
final Analyzer analyzer = state.analyzer(req.getParameter("analyzer"));
final Operator operator = "and".equalsIgnoreCase(req.getParameter("default_operator"))
? Operator.AND : Operator.OR;
final Query q = state.parse(queryString, operator, analyzer);
final JSONObject queryRow = new JSONObject();
queryRow.put("q", q.toString());
if (getBooleanParameter(req, "debug")) {
queryRow.put("plan", QueryPlan.toPlan(q));
queryRow.put("analyzer", analyzer.getClass());
}
queryRow.put("etag", etag);
if (getBooleanParameter(req, "rewrite")) {
final Query rewritten_q = q.rewrite(searcher
.getIndexReader());
queryRow.put("rewritten_q", rewritten_q.toString());
final JSONObject freqs = new JSONObject();
final Set<Term> terms = new HashSet<Term>();
rewritten_q.extractTerms(terms);
for (final Object term : terms) {
final int freq = searcher.getIndexReader().docFreq((Term) term);
freqs.put(term.toString(), freq);
}
queryRow.put("freqs", freqs);
} else {
// Perform the search.
final TopDocs td;
final StopWatch stopWatch = new StopWatch();
final boolean include_docs = getBooleanParameter(req,
"include_docs");
final int highlights = getIntParameter(req, "highlights", 0);
final int highlight_length = max(getIntParameter(req, "highlight_length", 18), 18); // min for fast term vector highlighter is 18
final boolean include_termvectors = getBooleanParameter(req, "include_termvectors");
final int limit = getIntParameter(req, "limit",
ini.getInt("lucene.limit", 25));
final Sort sort = CustomQueryParser.toSort(req
.getParameter("sort"));
final int skip = getIntParameter(req, "skip", 0);
final Set<String> fieldsToLoad;
if (req.getParameter("include_fields") == null) {
fieldsToLoad = null;
} else {
final String[] fields = Utils.splitOnCommas(
req.getParameter("include_fields"));
final List<String> list = Arrays.asList(fields);
fieldsToLoad = new HashSet<String>(list);
}
if (sort == null) {
td = searcher.search(q, null, skip + limit);
} else {
td = searcher.search(q, null, skip + limit, sort);
}
stopWatch.lap("search");
// Fetch matches (if any).
final int max = Math.max(0, Math.min(td.totalHits - skip,
limit));
final JSONArray rows = new JSONArray();
final String[] fetch_ids = new String[max];
for (int i = skip; i < skip + max; i++) {
final Document doc;
if (fieldsToLoad == null) {
doc = searcher.doc(td.scoreDocs[i].doc);
} else {
doc = searcher.doc(td.scoreDocs[i].doc, fieldsToLoad);
}
final JSONObject row = new JSONObject();
final JSONObject fields = new JSONObject();
final JSONObject highlight_rows = new JSONObject();
// Include stored fields.
for (final IndexableField f : doc.getFields()) {
if (!f.fieldType().stored()) {
continue;
}
final String name = f.name();
final Object value;
if (f.numericValue() != null) {
value = f.numericValue();
} else {
value = f.stringValue();
}
if (value != null) {
if ("_id".equals(name)) {
row.put("id", value);
} else {
if (!fields.has(name)) {
fields.put(name, value);
} else {
final Object obj = fields.get(name);
if (obj instanceof String || obj instanceof Number) {
final JSONArray arr = new JSONArray();
arr.put(obj);
arr.put(value);
fields.put(name, arr);
} else {
assert obj instanceof JSONArray;
((JSONArray) obj).put(value);
}
}
if (highlights > 0) {
String[] frags = fvh.getBestFragments(fvh.getFieldQuery(q), searcher.getIndexReader(), td.scoreDocs[i].doc, name, highlight_length, highlights);
highlight_rows.put(name, frags);
}
}
}
}