Hello,
In our app we perform issue search using Lucene index, but it takes 40-60 seconds to handle 10-15K issues. Quite often it takes even more time so that the whole search fails with TimeOut exception later in REST calls that trigger the search.
Any help/suggestions on what we do wrong is very much appreciated.
The IssueCollector code is:
public class IssueIdHitCollector extends SimpleCollector {
private static final Logger logger = LoggerFactory.getLogger(IssueIdHitCollector.class);
private final ObjLongConsumer<Document> issueCollector;
private final Set<String> fields;
private LeafReader leafReader;
public IssueIdHitCollector(ObjLongConsumer<Document> issueCollector, String... fields) {
this.issueCollector = issueCollector;
this.fields = (fields.length == 0 ? ImmutableSet.of(DocumentConstants.ISSUE_ID) : ImmutableSet.<String>builder().add(DocumentConstants.ISSUE_ID).add(fields).build());
}
protected void doSetNextReader(LeafReaderContext context) throws IOException {
this.leafReader = context.reader();
}
public boolean needsScores() {
return false;
}
public void collect(int doc) throws IOException {
try {
Document document = this.leafReader.document(doc, this.fields);
if (document != null) {
String v = document.get("issue_id");
try {
collectIssue(document, Long.parseLong(v));
} catch (NumberFormatException e) {
logger.warn("error reading issue document " + doc + " id [" + v + "]", e);
}
}
} catch (IOException e) {
logger.warn("error reading issue document " + doc, e);
}
}
private void collectIssue(Document document, long id) {
this.issueCollector.accept(document, id);
}
}
IssueConsumer code is:
public class IntervalIssuesConsumer implements ObjLongConsumer<Document> {
private List<IssueObject> issues;
private Estimation estimation;
public IntervalIssuesConsumer(Estimation estimation) {
issues = new ArrayList<>();
this.estimation = estimation;
}
public List<IssueObject> getIssues() {
return issues;
}
@Override
public void accept(Document d, long value) {
issues.add(createIssueObject(d));
}
private IssueObject createIssueObject(Document d) {
String estimate = "0";
switch (estimation.getType()) {
case EstimationType.FIELD: {
estimate = d.get(estimation.getField().getFieldId());
if (estimate == null) {
estimate = "0";
}
else if (EstimationField.isTimeEstimateField(estimation.getField().getFieldId())) {
estimate = String.valueOf(Long.parseLong(estimate, 36));
}
break;
}
case EstimationType.ISSUE_COUNT:
estimate = "1";
break;
}
return new IssueObject(
d.get(DocumentConstants.ISSUE_ID),
d.get(DocumentConstants.ISSUE_KEY),
d.get(DocumentConstants.ISSUE_TYPE),
d.get(DocumentConstants.ISSUE_CREATED),
d.get(DocumentConstants.ISSUE_STATUS),
d.get(DocumentConstants.ISSUE_SUMMARY),
null,
estimate
);
}
}