Search in sources :

Example 16 with ChangeStreamDocument

use of com.mongodb.client.model.changestream.ChangeStreamDocument in project spring-data-mongodb by spring-projects.

the class ChangeStreamTests method readsOnlyDiffForUpdateWhenNotMappedToDomainType.

// DATAMONGO-1803
@Test
void readsOnlyDiffForUpdateWhenNotMappedToDomainType() throws InterruptedException {
    CollectingMessageListener<ChangeStreamDocument<Document>, Document> messageListener = new CollectingMessageListener<>();
    ChangeStreamRequest<Document> request = new ChangeStreamRequest<>(messageListener, new ChangeStreamRequestOptions(null, "user", Duration.ofMillis(10), ChangeStreamOptions.builder().build()));
    Subscription subscription = container.register(request, Document.class);
    awaitSubscription(subscription);
    template.save(jellyBelly);
    template.update(User.class).matching(query(where("id").is(jellyBelly.id))).apply(Update.update("age", 8)).first();
    awaitMessages(messageListener, 2);
    assertThat(messageListener.getFirstMessage().getBody()).isEqualTo(new Document("_id", "id-1").append("user_name", "jellyBelly").append("age", 7).append("_class", User.class.getName()));
    assertThat(messageListener.getLastMessage().getBody()).isNull();
}
Also used : ChangeStreamDocument(com.mongodb.client.model.changestream.ChangeStreamDocument) Document(org.bson.Document) ChangeStreamDocument(com.mongodb.client.model.changestream.ChangeStreamDocument) BsonDocument(org.bson.BsonDocument) FullDocument(com.mongodb.client.model.changestream.FullDocument) ChangeStreamRequestOptions(org.springframework.data.mongodb.core.messaging.ChangeStreamRequest.ChangeStreamRequestOptions) RepeatFailedTest(org.junitpioneer.jupiter.RepeatFailedTest) Test(org.junit.jupiter.api.Test)

Example 17 with ChangeStreamDocument

use of com.mongodb.client.model.changestream.ChangeStreamDocument in project spring-data-mongodb by spring-projects.

the class ChangeStreamTests method useAggregationToFilterMessages.

// DATAMONGO-1803
@Test
public void useAggregationToFilterMessages() throws InterruptedException {
    CollectingMessageListener<ChangeStreamDocument<Document>, User> messageListener = new CollectingMessageListener<>();
    ChangeStreamRequest<User> request = // 
    ChangeStreamRequest.builder(messageListener).collection(// 
    "user").filter(newAggregation(match(// 
    new Criteria().orOperator(where("user_name").is("huffyFluffy"), where("user_name").is("jellyBelly"))))).build();
    Subscription subscription = container.register(request, User.class);
    awaitSubscription(subscription);
    template.save(jellyBelly);
    template.save(sugarSplashy);
    template.save(huffyFluffy);
    awaitMessages(messageListener);
    List<User> messageBodies = messageListener.getMessages().stream().map(Message::getBody).collect(Collectors.toList());
    assertThat(messageBodies).hasSize(2).doesNotContain(sugarSplashy);
}
Also used : ChangeStreamDocument(com.mongodb.client.model.changestream.ChangeStreamDocument) Criteria(org.springframework.data.mongodb.core.query.Criteria) Test(org.junit.Test)

Example 18 with ChangeStreamDocument

use of com.mongodb.client.model.changestream.ChangeStreamDocument in project spring-data-mongodb by spring-projects.

the class ChangeStreamTests method mapsTypedAggregationToFilterMessages.

// DATAMONGO-1803
@Test
public void mapsTypedAggregationToFilterMessages() throws InterruptedException {
    CollectingMessageListener<ChangeStreamDocument<Document>, User> messageListener = new CollectingMessageListener<>();
    ChangeStreamRequest<User> request = // 
    ChangeStreamRequest.builder().collection(// 
    "user").publishTo(// 
    messageListener).filter(newAggregation(User.class, // 
    match(new Criteria().orOperator(where("userName").is("huffyFluffy"), where("userName").is("jellyBelly"))))).build();
    Subscription subscription = container.register(request, User.class);
    awaitSubscription(subscription);
    template.save(jellyBelly);
    template.save(sugarSplashy);
    template.save(huffyFluffy);
    awaitMessages(messageListener);
    List<User> messageBodies = messageListener.getMessages().stream().map(Message::getBody).collect(Collectors.toList());
    assertThat(messageBodies).hasSize(2).doesNotContain(sugarSplashy);
}
Also used : ChangeStreamDocument(com.mongodb.client.model.changestream.ChangeStreamDocument) Criteria(org.springframework.data.mongodb.core.query.Criteria) Test(org.junit.Test)

Example 19 with ChangeStreamDocument

use of com.mongodb.client.model.changestream.ChangeStreamDocument in project mongo-java-driver by mongodb.

the class ChangeStreamSamples method main.

/**
 * Run this main method to see the output of this quick example.
 *
 * @param args takes an optional single argument for the connection string
 */
public static void main(final String[] args) {
    MongoClient mongoClient;
    if (args.length == 0) {
        // connect to the local database server
        mongoClient = MongoClients.create("mongodb://localhost:27017,localhost:27018,localhost:27019");
    } else {
        mongoClient = MongoClients.create(args[0]);
    }
    // Select the MongoDB database.
    MongoDatabase database = mongoClient.getDatabase("testChangeStreams");
    database.drop();
    sleep();
    // Select the collection to query.
    MongoCollection<Document> collection = database.getCollection("documents");
    /*
         * Example 1
         * Create a simple change stream against an existing collection.
         */
    System.out.println("1. Initial document from the Change Stream:");
    // Create the change stream cursor.
    MongoChangeStreamCursor<ChangeStreamDocument<Document>> cursor = collection.watch().cursor();
    // Insert a test document into the collection.
    collection.insertOne(Document.parse("{username: 'alice123', name: 'Alice'}"));
    ChangeStreamDocument<Document> next = cursor.next();
    System.out.println(next);
    cursor.close();
    sleep();
    /*
         * Example 2
         * Create a change stream with 'lookup' option enabled.
         * The test document will be returned with a full version of the updated document.
         */
    System.out.println("2. Document from the Change Stream, with lookup enabled:");
    // Create the change stream cursor.
    cursor = collection.watch().fullDocument(FullDocument.UPDATE_LOOKUP).cursor();
    // Update the test document.
    collection.updateOne(Document.parse("{username: 'alice123'}"), Document.parse("{$set : { email: 'alice@example.com'}}"));
    // Block until the next result is returned
    next = cursor.next();
    System.out.println(next);
    cursor.close();
    sleep();
    /*
         * Example 3
         * Create a change stream with 'lookup' option using a $match and ($redact or $project) stage.
         */
    System.out.println("3. Document from the Change Stream, with lookup enabled, matching `update` operations only: ");
    // Insert some dummy data.
    collection.insertMany(asList(Document.parse("{updateMe: 1}"), Document.parse("{replaceMe: 1}")));
    // Create $match pipeline stage.
    List<Bson> pipeline = singletonList(Aggregates.match(Filters.or(Document.parse("{'fullDocument.username': 'alice123'}"), Filters.in("operationType", asList("update", "replace", "delete")))));
    // Create the change stream cursor with $match.
    cursor = collection.watch(pipeline).fullDocument(FullDocument.UPDATE_LOOKUP).cursor();
    // Forward to the end of the change stream
    next = cursor.tryNext();
    // Update the test document.
    collection.updateOne(Filters.eq("updateMe", 1), Updates.set("updated", true));
    next = cursor.next();
    System.out.println(format("Update operationType: %s %n %s", next.getUpdateDescription(), next));
    // Replace the test document.
    collection.replaceOne(Filters.eq("replaceMe", 1), Document.parse("{replaced: true}"));
    next = cursor.next();
    System.out.println(format("Replace operationType: %s", next));
    // Delete the test document.
    collection.deleteOne(Filters.eq("username", "alice123"));
    next = cursor.next();
    System.out.println(format("Delete operationType: %s", next));
    cursor.close();
    sleep();
    /**
     * Example 4
     * Resume a change stream using a resume token.
     */
    System.out.println("4. Document from the Change Stream including a resume token:");
    // Get the resume token from the last document we saw in the previous change stream cursor.
    BsonDocument resumeToken = cursor.getResumeToken();
    System.out.println(resumeToken);
    // Pass the resume token to the resume after function to continue the change stream cursor.
    cursor = collection.watch().resumeAfter(resumeToken).cursor();
    // Insert a test document.
    collection.insertOne(Document.parse("{test: 'd'}"));
    // Block until the next result is returned
    next = cursor.next();
    System.out.println(next);
    cursor.close();
}
Also used : MongoClient(com.mongodb.client.MongoClient) BsonDocument(org.bson.BsonDocument) ChangeStreamDocument(com.mongodb.client.model.changestream.ChangeStreamDocument) Document(org.bson.Document) ChangeStreamDocument(com.mongodb.client.model.changestream.ChangeStreamDocument) BsonDocument(org.bson.BsonDocument) FullDocument(com.mongodb.client.model.changestream.FullDocument) MongoDatabase(com.mongodb.client.MongoDatabase) Bson(org.bson.conversions.Bson)

Example 20 with ChangeStreamDocument

use of com.mongodb.client.model.changestream.ChangeStreamDocument in project spring-data-mongodb by spring-projects.

the class ChangeStreamTask method initCursor.

/*
	 * (non-Javadoc)
	 * @see org.springframework.data.mongodb.core.messaging.CursorReadingTask#initCursor(org.springframework.data.mongodb.core.MongoTemplate, org.springframework.data.mongodb.core.messaging.SubscriptionRequest.RequestOptions, java.lang.Class)
	 */
@Override
protected MongoCursor<ChangeStreamDocument<Document>> initCursor(MongoTemplate template, RequestOptions options, Class<?> targetType) {
    List<Document> filter = Collections.emptyList();
    BsonDocument resumeToken = new BsonDocument();
    Collation collation = null;
    FullDocument fullDocument = ClassUtils.isAssignable(Document.class, targetType) ? FullDocument.DEFAULT : FullDocument.UPDATE_LOOKUP;
    BsonTimestamp startAt = null;
    boolean resumeAfter = true;
    if (options instanceof ChangeStreamRequest.ChangeStreamRequestOptions) {
        ChangeStreamOptions changeStreamOptions = ((ChangeStreamRequestOptions) options).getChangeStreamOptions();
        filter = prepareFilter(template, changeStreamOptions);
        if (changeStreamOptions.getFilter().isPresent()) {
            Object val = changeStreamOptions.getFilter().get();
            if (val instanceof Aggregation) {
                collation = ((Aggregation) val).getOptions().getCollation().map(org.springframework.data.mongodb.core.query.Collation::toMongoCollation).orElse(null);
            }
        }
        if (changeStreamOptions.getResumeToken().isPresent()) {
            resumeToken = changeStreamOptions.getResumeToken().get().asDocument();
            resumeAfter = changeStreamOptions.isResumeAfter();
        }
        fullDocument = changeStreamOptions.getFullDocumentLookup().orElseGet(() -> ClassUtils.isAssignable(Document.class, targetType) ? FullDocument.DEFAULT : FullDocument.UPDATE_LOOKUP);
        startAt = changeStreamOptions.getResumeBsonTimestamp().orElse(null);
    }
    MongoDatabase db = StringUtils.hasText(options.getDatabaseName()) ? template.getMongoDbFactory().getMongoDatabase(options.getDatabaseName()) : template.getDb();
    ChangeStreamIterable<Document> iterable;
    if (StringUtils.hasText(options.getCollectionName())) {
        iterable = filter.isEmpty() ? db.getCollection(options.getCollectionName()).watch(Document.class) : db.getCollection(options.getCollectionName()).watch(filter, Document.class);
    } else {
        iterable = filter.isEmpty() ? db.watch(Document.class) : db.watch(filter, Document.class);
    }
    if (!options.maxAwaitTime().isZero()) {
        iterable = iterable.maxAwaitTime(options.maxAwaitTime().toMillis(), TimeUnit.MILLISECONDS);
    }
    if (!resumeToken.isEmpty()) {
        if (resumeAfter) {
            iterable = iterable.resumeAfter(resumeToken);
        } else {
            iterable = iterable.startAfter(resumeToken);
        }
    }
    if (startAt != null) {
        iterable.startAtOperationTime(startAt);
    }
    if (collation != null) {
        iterable = iterable.collation(collation);
    }
    iterable = iterable.fullDocument(fullDocument);
    return iterable.iterator();
}
Also used : FullDocument(com.mongodb.client.model.changestream.FullDocument) ChangeStreamOptions(org.springframework.data.mongodb.core.ChangeStreamOptions) Document(org.bson.Document) ChangeStreamDocument(com.mongodb.client.model.changestream.ChangeStreamDocument) BsonDocument(org.bson.BsonDocument) FullDocument(com.mongodb.client.model.changestream.FullDocument) Collation(com.mongodb.client.model.Collation) ChangeStreamRequestOptions(org.springframework.data.mongodb.core.messaging.ChangeStreamRequest.ChangeStreamRequestOptions) BsonTimestamp(org.bson.BsonTimestamp) TypedAggregation(org.springframework.data.mongodb.core.aggregation.TypedAggregation) Aggregation(org.springframework.data.mongodb.core.aggregation.Aggregation) BsonDocument(org.bson.BsonDocument) MongoDatabase(com.mongodb.client.MongoDatabase)

Aggregations

ChangeStreamDocument (com.mongodb.client.model.changestream.ChangeStreamDocument)24 BsonDocument (org.bson.BsonDocument)16 Test (org.junit.Test)11 Test (org.junit.jupiter.api.Test)9 ChangeStreamRequestOptions (org.springframework.data.mongodb.core.messaging.ChangeStreamRequest.ChangeStreamRequestOptions)9 Document (org.bson.Document)8 RepeatFailedTest (org.junitpioneer.jupiter.RepeatFailedTest)8 FullDocument (com.mongodb.client.model.changestream.FullDocument)7 MongoDatabase (com.mongodb.client.MongoDatabase)2 BsonString (org.bson.BsonString)2 Bson (org.bson.conversions.Bson)2 Criteria (org.springframework.data.mongodb.core.query.Criteria)2 JsonTestServerVersionChecker.skipTest (com.mongodb.JsonTestServerVersionChecker.skipTest)1 MongoClient (com.mongodb.client.MongoClient)1 Collation (com.mongodb.client.model.Collation)1 Field (com.mongodb.client.model.Field)1 Instant (java.time.Instant)1 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1 BsonDocumentWriter (org.bson.BsonDocumentWriter)1 BsonTimestamp (org.bson.BsonTimestamp)1