Consider a aggregation, which is formed like:
MatchOperation matchOperation = match(Criteria.where("group").is("A")
.andOperator(Criteria.where("score").lt(50))) ;
SortOperation sortOperation = sort(Sort.by(Direction.DESC, "department"));
Aggregation aggregation = Aggregation.newAggregation(matchOperation, sortOperation) ;
I want to issue a bulk remove (or basically remove each document found as a result of above) using a Spring Boot application.
Problem:
Unable to find a suitable method to do so, and I want to achieve this using Aggregation only ie. don't want to switch to Query.
What I've tried already:
I have already tried using mongoTemplate.findAllAndRemove(), but it accepts a Query and I am using Aggregation.
I have also tried using
BulkOperations bulkOps = mongoTemplate.bulkOps(BulkMode.ORDERED, EntityName.class) ;
And then, bulkOps.remove() but this method also accepts a List<Query>
You can't remove using aggregation so I think there are two options:
Using your aggregate query to get all _ids and do a new Query to remove these _ids.
Something like this (not tested):
List<Document> result = mongoTemplate.aggregate(aggregation, "my_collection", Document.class).getMappedResults();
List<ObjectId> resultList = result.stream().map(item -> item.get("_id")).collect(Collectors.toList());
mongoTemplate.remove(new Query(Criteria.where("_id").in(resultList)), YourClass.class);
Create a new delete query. As you need to use delete maybe you can avoid aggregation simply using this:
mongoTemplate.remove(new Query(Criteria.where("group").is("A").andOperator(Criteria.where("score").lt(50))), YourClass.class);
Note that the criteria is the same as you have in the match. This is because is the same use it in a find/remove/update query and into an aggregation query
By the way, I don't understand why sort if you want to delete.
Related
How to copy a single document from one collection to anther in one go with Spring Data?
Right now, I am finding the document by id and save it to another collection. But thats 2 steps.
Is there anything like findAndCopy kind of functionality?
You can do it using Aggregation framework as shown below.
MatchOperation matchOperation = match(Criteria.where("somekey").is("someValue"));
ProjectionOperation projectionOperation = project().andExpression("someKey").as("Key")
.andExpression("otherKey").as("SomeOtherKey");
OutOperation outOperation = out("New_Collection_Name");
Aggregation aggregation = newAggregation(matchOperation, projectionOperation, outOperation);
mongoTemplate.aggregate(aggregation, "Existing_Collection_Name", ResultClass.class);
Here ResultClass should be defined based on fields that you use in projection.
If you want to write all the fields to new collection(and not only few), then you can remove projection operation in the above pipeline. ResultClass in this case will be same same as your Document(input) class
I write the criteria query like this
query.addCriteria(Criteria.where("_id").is(id));
but the result is {"_id":123456789123450} which is not searching result. What I need to change to search the result using the criteria query on _id?
There are two ways to do this
Query query = new Query(Criteria.where("id").is(new ObjectId(<id value>)));
Or Spring data MongoDB's findById
org.springframework.data.repository.CrudRepository.findById(String id);
https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/repository/CrudRepository.html#findById-ID-
I was looking to use the $natural operator in Spring Data MongoDB, as documented here:
https://docs.mongodb.org/v3.0/reference/operator/meta/natural/
Is this possible to do using the MongoTemplate class? Thanks.
It is possible to use $natural in at least three styles where 1. and 2. are probably what you're looking for:
1. Using Sort with Query
Query query = new Query().with(new Sort(Direction.ASC, "$natural"));
use the query afterwards with MongoTemplate. The query carries a sort document like:
{ "$natural" : 1}
2. Using BasicQuery
BasicQuery allows using own DBObjects for the query document, the fields ("projection") and sorting.
BasicQuery basicQuery = new BasicQuery(new BasicDBObject());
basicQuery.setSortObject(new BasicDBObject("$natural", 1));
3. Using execute and CollectionCallback
This is the most extensive way in which you're getting access to the DBCollection and you can use the native MongoDB driver API. See Spring Data Mongo docs for more details.
I have to generate a dynamic report.
I have a complex query which returns result using db.collection.find() and has millions of records in it.
Now I want to perform aggregate operation on this result.
I tried inserting into a collection and than executing aggregate function on it using below:
db.users.find().forEach( function(myDoc) { db.usersDummy.insert(myDoc); } );
But this does not seems to be feasible to temporarily insert data and then perform aggregate operation on it.
Is there any way mongoDB supports Temporary tables or perform aggregate operation directly on find result?
As suggested by JohnnyHK i am using $match in aggregation to run the huge collection instead of creating a dummy collection
So closing this question
I want to query item from mongoDB using morphia, but I found the order method has only one parameter, can I query data with multi order field like:
List items = Item.q().order("-updateTime").order("-createTime");
You just separate the fields with commas. The wiki has examples: https://github.com/mongodb/morphia/wiki/Query#sort
You can use
List items = Item.q().order("-updateTime,createTime,otherField").asList();