All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.pincette.mongo.streams.AddFields Maven / Gradle / Ivy

The newest version!
package net.pincette.mongo.streams;

import static java.util.stream.Collectors.toMap;
import static net.pincette.json.JsonUtil.from;
import static net.pincette.json.JsonUtil.isObject;
import static net.pincette.json.Transform.transform;
import static net.pincette.mongo.Expression.function;
import static net.pincette.rs.Mapper.map;
import static net.pincette.util.Collections.expand;
import static net.pincette.util.Collections.flatten;
import static net.pincette.util.Collections.merge;
import static net.pincette.util.Util.must;

import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.concurrent.Flow.Processor;
import java.util.function.Function;
import javax.json.JsonObject;
import javax.json.JsonValue;
import net.pincette.json.Transform.JsonEntry;
import net.pincette.json.Transform.Transformer;
import net.pincette.rs.streams.Message;

/**
 * The $addFields operator.
 *
 * @author Werner Donné
 */
class AddFields {
  private AddFields() {}

  private static JsonObject addFields(
      final JsonObject json, final Map> functions) {
    final Map newValues = applyFunctions(json, functions);

    return addNewFields(
        transform(
            json,
            new Transformer(
                e -> newValues.containsKey(e.path),
                e -> Optional.of(new JsonEntry(e.path, newValues.remove(e.path))))),
        newValues);
  }

  private static JsonObject addNewFields(
      final JsonObject json, final Map newValues) {
    return from(expand(merge(flatten(json, "."), flatten(newValues, ".")), "."));
  }

  private static Map applyFunctions(
      final JsonObject json, final Map> functions) {
    return functions.entrySet().stream()
        .collect(toMap(Entry::getKey, e -> e.getValue().apply(json)));
  }

  static Processor, Message> stage(
      final JsonValue expression, final Context context) {
    must(isObject(expression));

    final Map> functions =
        expression.asJsonObject().entrySet().stream()
            .collect(toMap(Entry::getKey, e -> function(e.getValue(), context.features)));

    return map(m -> m.withValue(addFields(m.value, functions)));
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy