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

com.mongodb.client.model.Updates Maven / Gradle / Ivy

Go to download

The Java operations layer for the MongoDB Java Driver. Third parties can wrap this layer to provide custom higher-level APIs

There is a newer version: 5.3.0-beta0
Show newest version
/*
 * Copyright 2008-present MongoDB, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.mongodb.client.model;

import com.mongodb.lang.Nullable;
import org.bson.BsonDocument;
import org.bson.BsonDocumentWriter;
import org.bson.BsonInt32;
import org.bson.BsonInt64;
import org.bson.BsonString;
import org.bson.BsonValue;
import org.bson.codecs.configuration.CodecRegistry;
import org.bson.conversions.Bson;

import java.util.List;
import java.util.Map;
import java.util.Objects;

import static com.mongodb.assertions.Assertions.notNull;
import static com.mongodb.client.model.BuildersHelper.encodeValue;
import static java.util.Arrays.asList;

/**
 * A factory for document updates. A convenient way to use this class is to statically import all of its methods, which allows usage like:
 * 
 *    collection.updateOne(eq("x", 1), set("x", 2));
 * 
* * @since 3.1 * @mongodb.driver.manual reference/operator/update/ Update Operators */ public final class Updates { /** * Combine a list of updates into a single update. * * @param updates the list of updates * @return a combined update */ public static Bson combine(final Bson... updates) { return combine(asList(updates)); } /** * Combine a list of updates into a single update. * * @param updates the list of updates * @return a combined update */ public static Bson combine(final List updates) { notNull("updates", updates); return new CompositeUpdate(updates); } /** * Creates an update that sets the value of the field with the given name to the given value. * * @param fieldName the non-null field name * @param value the value, which may be null * @param the value type * @return the update * @mongodb.driver.manual reference/operator/update/set/ $set */ public static Bson set(final String fieldName, @Nullable final TItem value) { return new SimpleUpdate<>(fieldName, value, "$set"); } /** * Creates an update that deletes the field with the given name. * * @param fieldName the non-null field name * @return the update * @mongodb.driver.manual reference/operator/update/unset/ $unset */ public static Bson unset(final String fieldName) { return new SimpleUpdate<>(fieldName, "", "$unset"); } /** * Creates an update that sets the values for the document, but only if the update is an upsert that results in an insert of a document. * * @param value the value * @return the update * @mongodb.driver.manual reference/operator/update/setOnInsert/ $setOnInsert * @since 3.10.0 * @see UpdateOptions#upsert(boolean) */ public static Bson setOnInsert(final Bson value) { return new SimpleBsonKeyValue("$setOnInsert", value); } /** * Creates an update that sets the value of the field with the given name to the given value, but only if the update is an upsert that * results in an insert of a document. * * @param fieldName the non-null field name * @param value the value, which may be null * @param the value type * @return the update * @mongodb.driver.manual reference/operator/update/setOnInsert/ $setOnInsert * @see UpdateOptions#upsert(boolean) */ public static Bson setOnInsert(final String fieldName, @Nullable final TItem value) { return new SimpleUpdate<>(fieldName, value, "$setOnInsert"); } /** * Creates an update that renames a field. * * @param fieldName the non-null field name * @param newFieldName the non-null new field name * @return the update * @mongodb.driver.manual reference/operator/update/rename/ $rename */ public static Bson rename(final String fieldName, final String newFieldName) { notNull("newFieldName", newFieldName); return new SimpleUpdate<>(fieldName, newFieldName, "$rename"); } /** * Creates an update that increments the value of the field with the given name by the given value. * * @param fieldName the non-null field name * @param number the value * @return the update * @mongodb.driver.manual reference/operator/update/inc/ $inc */ public static Bson inc(final String fieldName, final Number number) { notNull("number", number); return new SimpleUpdate<>(fieldName, number, "$inc"); } /** * Creates an update that multiplies the value of the field with the given name by the given number. * * @param fieldName the non-null field name * @param number the non-null number * @return the update * @mongodb.driver.manual reference/operator/update/mul/ $mul */ public static Bson mul(final String fieldName, final Number number) { notNull("number", number); return new SimpleUpdate<>(fieldName, number, "$mul"); } /** * Creates an update that sets the value of the field to the given value if the given value is less than the current value of the * field. * * @param fieldName the non-null field name * @param value the value * @param the value type * @return the update * @mongodb.driver.manual reference/operator/update/min/ $min */ public static Bson min(final String fieldName, final TItem value) { return new SimpleUpdate<>(fieldName, value, "$min"); } /** * Creates an update that sets the value of the field to the given value if the given value is greater than the current value of the * field. * * @param fieldName the non-null field name * @param value the value * @param the value type * @return the update * @mongodb.driver.manual reference/operator/update/min/ $min */ public static Bson max(final String fieldName, final TItem value) { return new SimpleUpdate<>(fieldName, value, "$max"); } /** * Creates an update that sets the value of the field to the current date as a BSON date. * * @param fieldName the non-null field name * @return the update * @mongodb.driver.manual reference/operator/update/currentDate/ $currentDate * @mongodb.driver.manual reference/bson-types/#date Date */ public static Bson currentDate(final String fieldName) { return new SimpleUpdate<>(fieldName, true, "$currentDate"); } /** * Creates an update that sets the value of the field to the current date as a BSON timestamp. * * @param fieldName the non-null field name * @return the update * @mongodb.driver.manual reference/operator/update/currentDate/ $currentDate * @mongodb.driver.manual reference/bson-types/#document-bson-type-timestamp Timestamp */ public static Bson currentTimestamp(final String fieldName) { return new SimpleUpdate<>(fieldName, new BsonDocument("$type", new BsonString("timestamp")), "$currentDate"); } /** * Creates an update that adds the given value to the array value of the field with the given name, unless the value is * already present, in which case it does nothing * * @param fieldName the non-null field name * @param value the value, which may be null * @param the value type * @return the update * @mongodb.driver.manual reference/operator/update/addToSet/ $addToSet */ public static Bson addToSet(final String fieldName, @Nullable final TItem value) { return new SimpleUpdate<>(fieldName, value, "$addToSet"); } /** * Creates an update that adds each of the given values to the array value of the field with the given name, unless the value is * already present, in which case it does nothing * * @param fieldName the non-null field name * @param values the values * @param the value type * @return the update * @mongodb.driver.manual reference/operator/update/addToSet/ $addToSet */ public static Bson addEachToSet(final String fieldName, final List values) { return new WithEachUpdate<>(fieldName, values, "$addToSet"); } /** * Creates an update that adds the given value to the array value of the field with the given name. * * @param fieldName the non-null field name * @param value the value, which may be null * @param the value type * @return the update * @mongodb.driver.manual reference/operator/update/push/ $push */ public static Bson push(final String fieldName, @Nullable final TItem value) { return new SimpleUpdate<>(fieldName, value, "$push"); } /** * Creates an update that adds each of the given values to the array value of the field with the given name. * * @param fieldName the non-null field name * @param values the values * @param the value type * @return the update * @mongodb.driver.manual reference/operator/update/push/ $push */ public static Bson pushEach(final String fieldName, final List values) { return new PushUpdate<>(fieldName, values, new PushOptions()); } /** * Creates an update that adds each of the given values to the array value of the field with the given name, applying the given * options for positioning the pushed values, and then slicing and/or sorting the array. * * @param fieldName the non-null field name * @param values the values * @param options the non-null push options * @param the value type * @return the update * @mongodb.driver.manual reference/operator/update/push/ $push */ public static Bson pushEach(final String fieldName, final List values, final PushOptions options) { return new PushUpdate<>(fieldName, values, options); } /** * Creates an update that removes all instances of the given value from the array value of the field with the given name. * * @param fieldName the non-null field name * @param value the value, which may be null * @param the value type * @return the update * @mongodb.driver.manual reference/operator/update/pull/ $pull */ public static Bson pull(final String fieldName, @Nullable final TItem value) { return new SimpleUpdate<>(fieldName, value, "$pull"); } /** * Creates an update that removes from an array all elements that match the given filter. * * @param filter the query filter * @return the update * @mongodb.driver.manual reference/operator/update/pull/ $pull */ public static Bson pullByFilter(final Bson filter) { return new Bson() { @Override public BsonDocument toBsonDocument(final Class tDocumentClass, final CodecRegistry codecRegistry) { BsonDocumentWriter writer = new BsonDocumentWriter(new BsonDocument()); writer.writeStartDocument(); writer.writeName("$pull"); encodeValue(writer, filter, codecRegistry); writer.writeEndDocument(); return writer.getDocument(); } }; } /** * Creates an update that removes all instances of the given values from the array value of the field with the given name. * * @param fieldName the non-null field name * @param values the values * @param the value type * @return the update * @mongodb.driver.manual reference/operator/update/pull/ $pull */ public static Bson pullAll(final String fieldName, final List values) { return new PullAllUpdate<>(fieldName, values); } /** * Creates an update that pops the first element of an array that is the value of the field with the given name. * * @param fieldName the non-null field name * @return the update * @mongodb.driver.manual reference/operator/update/pop/ $pop */ public static Bson popFirst(final String fieldName) { return new SimpleUpdate<>(fieldName, -1, "$pop"); } /** * Creates an update that pops the last element of an array that is the value of the field with the given name. * * @param fieldName the non-null field name * @return the update * @mongodb.driver.manual reference/operator/update/pop/ $pop */ public static Bson popLast(final String fieldName) { return new SimpleUpdate<>(fieldName, 1, "$pop"); } /** * Creates an update that performs a bitwise and between the given integer value and the integral value of the field with the given * name. * * @param fieldName the field name * @param value the value * @return the update */ public static Bson bitwiseAnd(final String fieldName, final int value) { return createBitUpdateDocument(fieldName, "and", value); } /** * Creates an update that performs a bitwise and between the given long value and the integral value of the field with the given name. * * @param fieldName the field name * @param value the value * @return the update * @mongodb.driver.manual reference/operator/update/bit/ $bit */ public static Bson bitwiseAnd(final String fieldName, final long value) { return createBitUpdateDocument(fieldName, "and", value); } /** * Creates an update that performs a bitwise or between the given integer value and the integral value of the field with the given * name. * * @param fieldName the field name * @param value the value * @return the update * @mongodb.driver.manual reference/operator/update/bit/ $bit */ public static Bson bitwiseOr(final String fieldName, final int value) { return createBitUpdateDocument(fieldName, "or", value); } /** * Creates an update that performs a bitwise or between the given long value and the integral value of the field with the given name. * * @param fieldName the field name * @param value the value * @return the update * @mongodb.driver.manual reference/operator/update/bit/ $bit */ public static Bson bitwiseOr(final String fieldName, final long value) { return createBitUpdateDocument(fieldName, "or", value); } /** * Creates an update that performs a bitwise xor between the given integer value and the integral value of the field with the given * name. * * @param fieldName the field name * @param value the value * @return the update */ public static Bson bitwiseXor(final String fieldName, final int value) { return createBitUpdateDocument(fieldName, "xor", value); } /** * Creates an update that performs a bitwise xor between the given long value and the integral value of the field with the given name. * * @param fieldName the field name * @param value the value * @return the update */ public static Bson bitwiseXor(final String fieldName, final long value) { return createBitUpdateDocument(fieldName, "xor", value); } private static Bson createBitUpdateDocument(final String fieldName, final String bitwiseOperator, final int value) { return createBitUpdateDocument(fieldName, bitwiseOperator, new BsonInt32(value)); } private static Bson createBitUpdateDocument(final String fieldName, final String bitwiseOperator, final long value) { return createBitUpdateDocument(fieldName, bitwiseOperator, new BsonInt64(value)); } private static Bson createBitUpdateDocument(final String fieldName, final String bitwiseOperator, final BsonValue value) { return new BsonDocument("$bit", new BsonDocument(fieldName, new BsonDocument(bitwiseOperator, value))); } private static class SimpleBsonKeyValue implements Bson { private final String fieldName; private final Bson value; SimpleBsonKeyValue(final String fieldName, final Bson value) { this.fieldName = notNull("fieldName", fieldName); this.value = notNull("value", value); } @Override public BsonDocument toBsonDocument(final Class tDocumentClass, final CodecRegistry codecRegistry) { BsonDocumentWriter writer = new BsonDocumentWriter(new BsonDocument()); writer.writeStartDocument(); writer.writeName(fieldName); encodeValue(writer, value, codecRegistry); writer.writeEndDocument(); return writer.getDocument(); } @Override public boolean equals(final Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } SimpleBsonKeyValue that = (SimpleBsonKeyValue) o; if (!fieldName.equals(that.fieldName)) { return false; } return value.equals(that.value); } @Override public int hashCode() { int result = fieldName.hashCode(); result = 31 * result + value.hashCode(); return result; } @Override public String toString() { return "SimpleBsonKeyValue{" + "fieldName='" + fieldName + '\'' + ", value=" + value + '}'; } } private static class SimpleUpdate implements Bson { private final String fieldName; private final TItem value; private final String operator; SimpleUpdate(final String fieldName, final TItem value, final String operator) { this.fieldName = notNull("fieldName", fieldName); this.value = value; this.operator = operator; } @Override public BsonDocument toBsonDocument(final Class tDocumentClass, final CodecRegistry codecRegistry) { BsonDocumentWriter writer = new BsonDocumentWriter(new BsonDocument()); writer.writeStartDocument(); writer.writeName(operator); writer.writeStartDocument(); writer.writeName(fieldName); encodeValue(writer, value, codecRegistry); writer.writeEndDocument(); writer.writeEndDocument(); return writer.getDocument(); } @Override public boolean equals(final Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } SimpleUpdate that = (SimpleUpdate) o; if (!fieldName.equals(that.fieldName)) { return false; } if (!Objects.equals(value, that.value)) { return false; } return Objects.equals(operator, that.operator); } @Override public int hashCode() { int result = fieldName.hashCode(); result = 31 * result + (value != null ? value.hashCode() : 0); result = 31 * result + (operator != null ? operator.hashCode() : 0); return result; } @Override public String toString() { return "Update{" + "fieldName='" + fieldName + '\'' + ", operator='" + operator + '\'' + ", value=" + value + '}'; } } private static class WithEachUpdate implements Bson { private final String fieldName; private final List values; private final String operator; WithEachUpdate(final String fieldName, final List values, final String operator) { this.fieldName = notNull("fieldName", fieldName); this.values = notNull("values", values); this.operator = operator; } @Override public BsonDocument toBsonDocument(final Class tDocumentClass, final CodecRegistry codecRegistry) { BsonDocumentWriter writer = new BsonDocumentWriter(new BsonDocument()); writer.writeStartDocument(); writer.writeName(operator); writer.writeStartDocument(); writer.writeName(fieldName); writer.writeStartDocument(); writer.writeStartArray("$each"); for (TItem value : values) { encodeValue(writer, value, codecRegistry); } writer.writeEndArray(); writeAdditionalFields(writer, tDocumentClass, codecRegistry); writer.writeEndDocument(); writer.writeEndDocument(); writer.writeEndDocument(); return writer.getDocument(); } protected void writeAdditionalFields(final BsonDocumentWriter writer, final Class tDocumentClass, final CodecRegistry codecRegistry) { } protected String additionalFieldsToString() { return ""; } @Override public boolean equals(final Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } WithEachUpdate that = (WithEachUpdate) o; if (!fieldName.equals(that.fieldName)) { return false; } if (!values.equals(that.values)) { return false; } return Objects.equals(operator, that.operator); } @Override public int hashCode() { int result = fieldName.hashCode(); result = 31 * result + values.hashCode(); result = 31 * result + (operator != null ? operator.hashCode() : 0); return result; } @Override public String toString() { return "Each Update{" + "fieldName='" + fieldName + '\'' + ", operator='" + operator + '\'' + ", values=" + values + additionalFieldsToString() + '}'; } } private static class PushUpdate extends WithEachUpdate { private final PushOptions options; PushUpdate(final String fieldName, final List values, final PushOptions options) { super(fieldName, values, "$push"); this.options = notNull("options", options); } @Override protected void writeAdditionalFields(final BsonDocumentWriter writer, final Class tDocumentClass, final CodecRegistry codecRegistry) { Integer position = options.getPosition(); if (position != null) { writer.writeInt32("$position", position); } Integer slice = options.getSlice(); if (slice != null) { writer.writeInt32("$slice", slice); } Integer sort = options.getSort(); if (sort != null) { writer.writeInt32("$sort", sort); } else { Bson sortDocument = options.getSortDocument(); if (sortDocument != null) { writer.writeName("$sort"); encodeValue(writer, sortDocument, codecRegistry); } } } @Override public boolean equals(final Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } if (!super.equals(o)) { return false; } PushUpdate that = (PushUpdate) o; return options.equals(that.options); } @Override public int hashCode() { int result = super.hashCode(); result = 31 * result + options.hashCode(); return result; } @Override protected String additionalFieldsToString() { return ", options=" + options; } } private static class PullAllUpdate implements Bson { private final String fieldName; private final List values; PullAllUpdate(final String fieldName, final List values) { this.fieldName = notNull("fieldName", fieldName); this.values = notNull("values", values); } @Override public BsonDocument toBsonDocument(final Class tDocumentClass, final CodecRegistry codecRegistry) { BsonDocumentWriter writer = new BsonDocumentWriter(new BsonDocument()); writer.writeStartDocument(); writer.writeName("$pullAll"); writer.writeStartDocument(); writer.writeName(fieldName); writer.writeStartArray(); for (TItem value : values) { encodeValue(writer, value, codecRegistry); } writer.writeEndArray(); writer.writeEndDocument(); writer.writeEndDocument(); return writer.getDocument(); } @Override public boolean equals(final Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } PullAllUpdate that = (PullAllUpdate) o; if (!fieldName.equals(that.fieldName)) { return false; } return values.equals(that.values); } @Override public int hashCode() { int result = fieldName.hashCode(); result = 31 * result + values.hashCode(); return result; } @Override public String toString() { return "Update{" + "fieldName='" + fieldName + '\'' + ", operator='$pullAll'" + ", value=" + values + '}'; } } private static class CompositeUpdate implements Bson { private final List updates; CompositeUpdate(final List updates) { this.updates = updates; } @Override public BsonDocument toBsonDocument(final Class tDocumentClass, final CodecRegistry codecRegistry) { BsonDocument document = new BsonDocument(); for (Bson update : updates) { BsonDocument rendered = update.toBsonDocument(tDocumentClass, codecRegistry); for (Map.Entry element : rendered.entrySet()) { if (document.containsKey(element.getKey())) { BsonDocument currentOperatorDocument = (BsonDocument) element.getValue(); BsonDocument existingOperatorDocument = document.getDocument(element.getKey()); for (Map.Entry currentOperationDocumentElements : currentOperatorDocument.entrySet()) { existingOperatorDocument.append(currentOperationDocumentElements.getKey(), currentOperationDocumentElements.getValue()); } } else { document.append(element.getKey(), element.getValue()); } } } return document; } @Override public boolean equals(final Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } CompositeUpdate that = (CompositeUpdate) o; return Objects.equals(updates, that.updates); } @Override public int hashCode() { return updates != null ? updates.hashCode() : 0; } @Override public String toString() { return "Updates{" + "updates=" + updates + '}'; } } private Updates() { } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy