in metron-platform/metron-solr/metron-solr-common/src/main/java/org/apache/metron/solr/dao/SolrMetaAlertSearchDao.java [118:202]
public SearchResponse search(SearchRequest searchRequest) throws InvalidSearchException {
// Need to wrap such that two things are true
// 1. The provided query is true OR nested query on the alert field is true
// 2. Metaalert is active OR it's not a metaalert
String activeStatusClause =
MetaAlertConstants.STATUS_FIELD + ":" + MetaAlertStatus.ACTIVE.getStatusString();
String metaalertTypeClause = config.getSourceTypeField() + ":" + MetaAlertConstants.METAALERT_TYPE;
// Use the 'v=' form in order to ensure complex clauses are properly handled.
// Per the docs, the 'which=' clause should be used to identify all metaalert parents, not to
// filter
// Status is a filter on parents and must be done outside the '!parent' construct
String parentChildQuery =
"(+" + activeStatusClause + " +" + "{!parent which=" + metaalertTypeClause + " v='"
+ searchRequest.getQuery() + "'})";
// Put everything together to get our full query
// The '-metaalert:[* TO *]' construct is to ensure the field doesn't exist on or is empty for
// plain alerts.
// Also make sure that it's not a metaalert
String fullQuery =
"(" + searchRequest.getQuery() + " AND -" + MetaAlertConstants.METAALERT_FIELD + ":[* TO *]"
+ " AND " + "-" + metaalertTypeClause + ")" + " OR " + parentChildQuery;
LOG.debug("MetaAlert search query {}", fullQuery);
searchRequest.setQuery(fullQuery);
// Build the custom field list
List<String> fields = searchRequest.getFields();
String fieldList = "*";
if (fields != null) {
fieldList = StringUtils.join(fields, ",");
}
LOG.debug("MetaAlert Search Field list {}", fullQuery);
SearchResponse results = solrSearchDao.search(searchRequest, fieldList);
LOG.debug("MetaAlert Search Number of results {}", results.getResults().size());
// Unfortunately, we can't get the full metaalert results at the same time
// Get them in a second query.
// However, we can only retrieve them if we have the source type field (either explicit or
// wildcard).
if (fieldList.contains("*") || fieldList.contains(config.getSourceTypeField())) {
List<String> metaalertGuids = new ArrayList<>();
for (SearchResult result : results.getResults()) {
if (result.getSource().get(config.getSourceTypeField())
.equals(MetaAlertConstants.METAALERT_TYPE)) {
// Then we need to add it to the list to retrieve child alerts in a second query.
metaalertGuids.add(result.getId());
}
}
LOG.debug("MetaAlert Search guids requiring retrieval: {}", metaalertGuids);
// If we have any metaalerts in our result, attach the full data.
if (metaalertGuids.size() > 0) {
Map<String, String> params = new HashMap<>();
params.put("fl", fieldList + ",[child parentFilter=" + metaalertTypeClause + " limit=999]");
SolrParams solrParams = new MapSolrParams(params);
try {
SolrDocumentList solrDocumentList = solrClient
.getById(METAALERTS_COLLECTION, metaalertGuids, solrParams);
Map<String, Document> guidToDocuments = new HashMap<>();
for (SolrDocument doc : solrDocumentList) {
Document document = SolrUtilities.toDocument(doc);
guidToDocuments.put(document.getGuid(), document);
}
// Run through our results and update them with the full metaalert
for (SearchResult result : results.getResults()) {
Document fullDoc = guidToDocuments.get(result.getId());
if (fullDoc != null) {
result.setSource(fullDoc.getDocument());
}
}
} catch (SolrServerException | IOException e) {
throw new InvalidSearchException("Error when retrieving child alerts for metaalerts", e);
}
}
}
return results;
}