Filetr items using mongotemplate - aggregation in spring boot - mongodb

I am trying to filter the products based on "cashback" offer using filter, but it is not working.Thanks in advance
My sprinboot method is:
public List<ProductsObj> getAllCashbackItems() {
Query query = new Query();
query.addCriteria(Criteria.where("listOfPromotions").in("cashback"));
Aggregation aggregation = newAggregation(
project().and(filter("listOfPromotions")
.as("item")
.by(valueOf(
"item.promotionName")
.equalToValue(
"cashback")))
.as("listOfPromotions")
);
return mongoTemplate.aggregate(aggregation, "productsObj", ProductsObj.class).getMappedResults();
}
My collection is look alike:
[
{
"_id": "5be29135f590eb09a079951a",
"name": "tennis ball",
"price": "1500",
"category": "sports",
"listOfPromotions": [
{
"promotionName": "cashback",
"percentage": 12
}
]
},
{
"_id": "5be29142f590eb09a079951b",
"name": "volley ball",
"price": "600",
"category": "sports",
"listOfPromotions": [
{
"promotionName": "dham dhamaal",
"percentage": 6
}
]
},
{
"_id": "5be2914ef590eb09a079951c",
"name": "Dinning table",
"price": "15000",
"category": "furnitures",
"listOfPromotions": [
{
"promotionName": "cashback",
"percentage": 6
},
{
"promotionName": "dham dhamaal",
"percentage": 10
}
]
}
]
My ProductsObj POJO class is :-
#Document(collection = "productsObj")
public class ProductsObj {
#Id
public ObjectId _id;
#Indexed
public String name;
public String price;
public String category;
public List<Promotion> listOfPromotions;
//constructors
//getters and setters
}
I am trying filter the object based on above mentioned criteria (i.e., cashback offer) In Promotions entity class contains promotionName and percentage.

I found the solution instead of simple criteria query i tried aggregation.
#RequestMapping(value = "/getcashbackitems", method = RequestMethod.GET)
public List<ProductsObj> getAllCashbackItems() {
Query query = new Query();
query.addCriteria(Criteria.where("listOfPromotions.promotionName").is("cashback"));
return mongoTemplate.find(query, ProductsObj.class);
}
Thanks for your responses :)

Related

I want to fetch second children data with query or query criteria

I am trying to fetch the children items fields
It is a nested document something like this
{
"title": "home",
"active": false,
"level": "1",
"children": [
{
"id": 1,
"title": "clothing",
"type": "sub",
"active": false,
"level": "2",
"children": [
{
"id":1,
"title": "New",
"type": "sup",
"active": false,
"level": "3",
}
]
}
]
}
This is my controller get Mapping for fetch submenu items fields
I am trying to fetch this with Query (Criteria) but it is not working
#GetMapping("/menus/{id}/submenu/{Id}/children/{childId}")
public Children findChildrenById(SubMenu subMenu, #PathVariable("id") long id,
#PathVariable("Id") long submenuId, #PathVariable("childId") long childId) {
Query query = new Query();
query.addCriteria(
Criteria.where("id").is(id).and("children.id").is(submenuId).and("children.children.$[].id").is(childId));
if (subMenu.getChildren() != null) {
for (Children child : subMenu
.getChildren()) {
return template.findOne(query, child.getClass());
}
}
return null;
}
I Want to fetch the nested document
Try this (and read comments in code for infos):
#PatchMapping("/menus-items-childrens/{id}")
public MenuItems updateSubMenuItems(#RequestBody MenuItems menuItems, #PathVariable("id") long id) {
Query query = new Query();
// assuming you want to update all the nested documents given the id of the main document
// you only need to filter on the id field
query.addCriteria(Criteria.where("id").is(id));
// '$[]' is required to update all nested documents
Update update = new Update().set("children.$[].active", true);
return MongoOperations.findAndModify(query, update, MenuItems.class);
}
See https://www.mongodb.com/docs/drivers/node/current/fundamentals/crud/write-operations/embedded-arrays/#matching-all-array-elements for more info

Mongo Query condition on third-level attribute

I have a relatively "simple" collection and query requirement.... I need help with the right syntax. :)
Here is the document definition in Java.
public class Entity {
private String _id = null;
private String name = null;
private Map<String, Object> attributes = new Hashmap<String, Object>();
}
Sample data inserted are like
{
"_id": "pk1",
"name": "Item 1",
"attributes": {
"en": { "attr1": "value 1 in English", "attr2": "value 2 in English"},
"es": { "attr1": "value 1 in Spanish", "attr2": "value 2 in Spanish"}
}
}
{
"_id": "pk2",
"name": "Item 2",
"attributes": {
"en": { "attr1": "value 1 in English", "attr2": "value 2 in English"},
"ms": { "attr1": "value 1 in Malay", "attr2": "value 2 in Malay"}
}
}
The language (key) of the map is an example of user provided (thus unpredictable) keys. I want a simple query syntax to be able fetch documents based on the attributes. For example, I want to put in a criteria "'attr1' contains 'value 1'" and query returns both docs, 'Item 1' and 'Item 2'.
Thanks in advance.

How to findById in Mongo, because of different format _id in database and API response

I'm using mongoDB - saving works well, but I have problem with findById:
#Repository
public class DataRepository {
private final MongoTemplate mongoTemplate;
#Autowired
public DataRepository(MongoTemplate mongoTemplate) {
this.mongoTemplate = mongoTemplate;
}
public DBObject save(DBObject jsonToSave, String collectionName) {
return mongoTemplate.save(jsonToSave, collectionName);
}
}
In my database _id is stored normally:
but, when I get Api response I got _id in weird format and I dont know how to us this _id object to query:
"_id": {
"timestamp": 1560243698,
"machineIdentifier": 777068,
"processIdentifier": -26590,
"counter": 14453904,
"timeSecond": 1560243698,
"time": 1560243698000,
"date": 1560243698000
},
Part of my controller which returns _id in weird format:
#PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity save(#RequestBody String json) {
DBObject dbObject = BasicDBObject.parse(json);
return ResponseEntity.ok().body(dataRepository.save(dbObject, serviceName));
}
I there any way to return _id in format like it is in database?

Jensseger Mongodb Laravel - Order By Attribute On Embeded Document

How can i order by attributes on a subdocument (lazy-loaded from belongsTo relation)?
I have:
Message::with(['conversation'])
->where(.....)
->get()
This returns:
[
{
"_id": "5aee075893782d1b1f460b13",
......
"updated_at": "2018-05-05 19:34:48",
"created_at": "2018-05-05 19:34:48",
"conversation": {
"_id": "5aee075793782d1b1f460b12",
"updated_at": "2018-05-06 12:21:23",
"created_at": "2018-05-05 19:34:47",
"messageCount": 5
}
}
]
I now need to order (the messages) by updated_at in conversation. I have tried ->orderBy('conversation.updated_at','desc'), but with no luck. I am guessing that the problem is that the conversation object is not available to orderBy due to lazy-loading...
Add this relation to the Message::class
public function conversationLatestFirst(): HasMany
{
return $this->hasMany(Conversation::class)->orderByDesc('created_at');
}
Then you should be able to query by
Message::with(['conversationLatestFirst'])
->where(.....)
->get()

Web API returns XML and Json, only want Json

Hi I am trying to create web api that I can call to view all the documents in the MongoDB, now the documents are very large and are heavily nested, I have Managed to return the document but in Json with the headers in XML.
I need to return this entire thing in Json!
This code takes the BsonDocument Product and returns this as Json because without this I get an error:
[JsonIgnore]
public BsonDocument Product { get; set; }
[DataMember]
public string Product
{
get { return Product .ToJson(); }
set { Product = BsonDocument.Parse(value); }
}
Here is a sample of the Document(This is a basic example, the actual document is much larger with deeper levels:
{
"product": {
"Type": "Phone",
"Size": {
"Height": 10,
"Lenght": 5,
"Weight": 30
}
"Make": "Apple"
"Model": {
"Name": "IPhone",
"Range": "4s"
}
}
}
it returns as
<Product>
{"product": {"Type": "Phone","Size": {"Height": 10,"Lenght": 5,"Weight": 30}"Make": "Apple", "Model": {"Name": "IPhone","Range": "4s"}}}
</Product>
How do i fix this?
How do i fix this?
Like this:
public HttpResponseMessage Get()
{
MyViewModel model = ...
// This will contain the JSON you want to return to the client
string product = model.Product;
var response = new HttpResponseMessage();
response.Content = new StringContent(product, Encoding.UTF8, "application/json");
return response;
}