Search in sources :

Example 1 with CompositeTerm

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;
}
Also used : Composite(datawave.query.composite.Composite) ArrayList(java.util.ArrayList) Date(java.util.Date) CompositeTerm(datawave.query.composite.CompositeTerm) JexlNode(org.apache.commons.jexl2.parser.JexlNode) Collection(java.util.Collection) Map(java.util.Map) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap)

Aggregations

Composite (datawave.query.composite.Composite)1 CompositeTerm (datawave.query.composite.CompositeTerm)1 ArrayList (java.util.ArrayList)1 Collection (java.util.Collection)1 Date (java.util.Date)1 HashMap (java.util.HashMap)1 LinkedHashMap (java.util.LinkedHashMap)1 Map (java.util.Map)1 JexlNode (org.apache.commons.jexl2.parser.JexlNode)1