use of datawave.query.composite.CompositeTerm in project datawave by NationalSecurityAgency.
the class ExpandCompositeTerms method findComposites.
/**
* Returns a list of composites that can be generated from the given leaf nodes and anded nodes. The used leaf nodes and anded nodes will be returned via
* their respective parameters.
*
* @param compositeToFieldMapSet
* A set of composite fields, mapped to their component fields which can be created with the given leaf and anded nodes
* @param leafNodes
* A multimap of leaf child nodes, keyed by field name, from the parent node
* @param andedNodes
* A multimap of anded nodes, keyed by field name, passed down from our ancestors
* @param usedLeafNodes
* A multimap of used leaf child nodes, keyed by field name, used to create the returned composites
* @param usedAndedNodes
* A multimap of used anded nodes, keyed by field name, used to create the returned composites
* @return A list of composites which can be created from the given leaf and anded nodes
*/
private List<Composite> findComposites(List<Entry<String, Collection<String>>> compositeToFieldMapSet, Multimap<String, JexlNode> leafNodes, Multimap<String, JexlNode> andedNodes, Multimap<String, JexlNode> usedLeafNodes, Multimap<String, JexlNode> usedAndedNodes) {
List<Composite> composites = new ArrayList<>();
// once a leaf node is used to create a composite, take it out of the rotation
Multimap<String, JexlNode> remainingLeafNodes = LinkedHashMultimap.create();
remainingLeafNodes.putAll(leafNodes);
// once an anded node is used to create a composite, take it out of the rotation
Multimap<String, JexlNode> remainingAndedNodes = LinkedHashMultimap.create();
remainingAndedNodes.putAll(andedNodes);
// look at each potential composite name to see if its fields are all available as keys in the childNodeMap
for (Map.Entry<String, Collection<String>> compositeToFieldMap : compositeToFieldMapSet) {
String compositeField = compositeToFieldMap.getKey();
List<String> componentFields = new ArrayList<>(compositeToFieldMap.getValue());
// is this a query against a composite field with old data whose date range predates the transition date?
if (CompositeIngest.isOverloadedCompositeField(config.getCompositeToFieldMap(), compositeField) && config.getCompositeTransitionDates().containsKey(compositeField)) {
Date transitionDate = config.getCompositeTransitionDates().get(compositeField);
if (config.getEndDate().compareTo(transitionDate) < 0)
continue;
}
// @formatter:off
boolean leafNodeFieldPresent = componentFields.stream().anyMatch(componentField -> remainingLeafNodes.keySet().contains(componentField));
// only build this composite if one of the components is a leaf node
if (!leafNodeFieldPresent)
continue;
// @formatter:off
boolean allRequiredFieldsPresent = componentFields.stream().allMatch(componentField -> remainingLeafNodes.keySet().contains(componentField) || remainingAndedNodes.keySet().contains(componentField));
// only build this composite if we have all of the required component fields
if (!allRequiredFieldsPresent)
continue;
// we have what we need to make a composite
List<Composite> tempComposites = new ArrayList<>();
Composite baseComp = new CompositeTerm(compositeField, config.getCompositeFieldSeparators().get(compositeField));
tempComposites.add(baseComp);
// keep track of the used nodes
Multimap<String, JexlNode> tempUsedLeafNodes = LinkedHashMultimap.create();
Multimap<String, JexlNode> tempUsedAndedNodes = LinkedHashMultimap.create();
// composite, creating additional nodes when necessary
for (int i = 0; i < componentFields.size(); i++) {
String componentField = componentFields.get(i);
Collection<JexlNode> nodes = Lists.newArrayList();
// add any required leaf nodes
for (JexlNode node : remainingLeafNodes.get(componentField)) {
JexlNode trimmedNode = getLeafNode(node);
if (trimmedNode != null && isNodeValid(trimmedNode, i, componentFields.size(), isFixedLengthField(componentField))) {
nodes.add(trimmedNode);
tempUsedLeafNodes.put(componentField, node);
}
}
// add any required anded nodes
for (JexlNode node : remainingAndedNodes.get(componentField)) {
JexlNode trimmedNode = getLeafNode(node);
if (trimmedNode != null && isNodeValid(trimmedNode, i, componentFields.size(), isFixedLengthField(componentField))) {
nodes.add(trimmedNode);
tempUsedAndedNodes.put(componentField, node);
}
}
// if at any point we run out of eligible nodes, then we have failed to build the composite, and need to stop
if (nodes.isEmpty()) {
tempComposites.clear();
break;
}
tempComposites = updateComposites(tempComposites, nodes);
// then we failed to update the composites
if (tempComposites.isEmpty())
break;
}
if (!tempComposites.isEmpty()) {
// save the found composites
composites.addAll(tempComposites);
// keep track of the used nodes
if (usedLeafNodes != null)
usedLeafNodes.putAll(tempUsedLeafNodes);
if (usedAndedNodes != null)
usedAndedNodes.putAll(tempUsedAndedNodes);
// take the used nodes out of the rotation
for (Entry<String, JexlNode> usedNode : tempUsedLeafNodes.entries()) remainingLeafNodes.remove(usedNode.getKey(), usedNode.getValue());
for (Entry<String, JexlNode> usedNode : tempUsedAndedNodes.entries()) remainingAndedNodes.remove(usedNode.getKey(), usedNode.getValue());
}
}
return composites;
}
Aggregations