mongodb criteria query for primary key _id? - mongodb

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-

Related

Bulk Removing documents using Spring Data MongoDB Aggregation

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.

MongoDB sort with score for text seach along with other criteria spring data

I have mongo document for ecommerce products. I want to sort based on search score. I have other parameters also in find clause. My query is:
db.getCollection('product').find({category_id:42, $text:
{$search:'red'}},{'score': {'$meta': 'textScore'}}).sort({'score': {'$meta': 'textScore'}}).limit(50)
How to perform same in spring data?
I have used query and andcriteria but not able to sort based on score:
Query query = new Query();
query.addCriteria(Criteria.where("category_id").is(42));
query.addCriteria(TextCriteria.forDefaultLanguage().
matching("red"));
mongoTemplate.find(query, A.class, "product");
But here no option to sort using score. How to sort based on score?
Please have a look at the reference documentation and use a TextQuery to apply sorting by score.
TextQuery query = new TextQuery(TextCriteria.forDefaultLanguage().matching("red"));
query.addCriteria(Criteria.where("category_id").is(42));
query.sortByScore();
I created DATAMONGO-2407 to improve the docs by making the sort option more visible.

MongoDB sort performance when used with $in query

I have a collection product in my DB. Below is one sample document:
{
"sku_id":"12345678",
"priduct_name":"milk",
"product_rank":3,
"product_price": 2.4
}
There are 100k such unique documents in our collection.
I want to query this collection using $in query, as shown below.
db.product.find({"sku_id" :{$in :["12345678","23213"]}}).sort( { product_rank: 1 } )
Our requirement is to search documents based on $in query and sort any field in document(asc or desc).
I have created both forward and reverse index on all fields for this collection.
Note: This sku_id array inside $in query can have 1000+ sku_ids.
My doubt is if I use the filter like $in with an array of sku_id and get the sorted result on any field, will it use the index for sorting or will it sort at query time?
Mongo allows you to find out if a query will use an index. As the find operation returns a cursor you can extend the method chain to include an explain() command which does exactly what you need. (suggest you use db.product.find(...).sort(...).explain('executionStats'))
Will it use the index for sorting or will it sort at query time?
The index created on the product_rank will be used in the query but, not an index on the sku_id alone. Instead create a compound index with both product_rank and sku_id(asc and desc).

Is it possible to use the Mongo $natural operator in Spring Data?

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.

Does the document in the db have to match the schema exactly in order to populate the queried doc?

My model is only querying the _id of the document. Does the document in the db have to match the schema exactly in order to populate the queried doc? For example. If my schema is {FirstName:String, LastName:String} and I insert {FirstName:'Rocky'} in the mongo term, would my Mongoose query only query the _id?
Schema: https://gist.github.com/fourq/5118f6237bf2fcc38a4b
Inserted Data: https://gist.github.com/fourq/d86d1b7b446f754efa17
What I get back when I query: https://gist.github.com/fourq/1fbbe6c8126b238a9b02
It was my lack of understanding on how to query the items I needed. I resolved this.