Related
I saw several articles here on stackoverflow but I couldn't get my pagination working with mongodb and spring boot. The code always returns only one result when I change the value of the limit or skip variable the result is always nothing.
My Repository:
public interface CategoryProductRepository extends MongoRepository<CategoryProduct, String> {
#Aggregation(pipeline = {
"{ '$match': { 'categories.category_id' : ?0 } }",
"{ '$skip' : ?1 }",
"{ '$limit' : ?2 }"
})
List<CategoryProduct> findCategoriesCategoryId(
Long field0,
Long skip,
Long limit
);
}
My structure:
[
{
"product_id": 4,
"id_colletion": 4,
"product_tite": "Testar",
"product_quant": 50,
"product_slug": "slug6",
"product_active": "ativo",
"product_description": "description",
"product_price_un": 50,
"product_price_kg": 10.25,
"star": 0,
"photos": [
{
"photo": "url",
"type": "mini",
"title": "título",
"active": "ativo"
},
{
"photo": "url 2",
"type": "mini",
"title": "título 2",
"active": "ativo"
}
],
"categories": [
{
"category_id": 1,
"name": "categoria 1",
"active": "ativo"
},
{
"category_id": 2,
"name": "categoria 2",
"active": "ativo"
}
]
},
{
"product_id": 5,
"id_colletion": 5,
"product_tite": "new",
"product_quant": 50,
"product_slug": "slugnew",
"product_active": "ativo",
"product_description": "descriptionnew",
"product_price_un": 50,
"product_price_kg": 10.25,
"star": 0,
"photos": [
{
"photo_id": 13,
"photo": "photo 11",
"type": "mini",
"title": "photo 11",
"active": "ativo"
}
],
"categories": [
{
"category_id": 1,
"name": "categoria 1",
"active": "ativo"
}
]
},
{
"product_id": 9,
"id_colletion": 9,
"product_tite": "2",
"product_quant": 2,
"product_slug": "slugnew2",
"product_active": "ativo",
"product_description": "2",
"product_price_un": 2,
"product_price_kg": 2,
"star": 0,
"photos": [
{
"photo": "photo 2",
"type": "mini",
"title": "photo 2",
"active": "desativo"
}
],
"categories": [
{
"category_id": 2,
"name": "categoria 2",
"active": "ativo"
}
]
}
]
Does anyone have any idea where my mistake is?
[SOLVED]
I was inserting the limit and skip wrong but the code works fine
I can't get collection.distinct to work for me on db.version '4.4.3'. I'm following the example at https://docs.mongodb.com/manual/reference/command/distinct/
{ "_id": 1, "dept": "A", "item": { "sku": "111", "color": "red" }, "sizes": [ "S", "M" ] }
{ "_id": 2, "dept": "A", "item": { "sku": "111", "color": "blue" }, "sizes": [ "M", "L" ] }
{ "_id": 3, "dept": "B", "item": { "sku": "222", "color": "blue" }, "sizes": "S" }
{ "_id": 4, "dept": "A", "item": { "sku": "333", "color": "black" }, "sizes": [ "S" ] }
Then run
db.runCommand ( { distinct: "inventory", key: "dept" } )
I get
{ values: [], ok: 1 }
This doesn't work either:
db.inventory.distinct( "dept" )
[]
I can't get it to work on a local server or a remote server. What gives?
I want to find an easy way to combine 3 ratings together for a mongoDB query. Specifically, is there some way to combine 3 aggregate calls in one. So for example i have the below data. Which lists ratings for movies, either in imbd.rating, tomato.rating or metacritic, I'd like to find the top 2 movies for each of these ratings. The bottom query is how i'm fetching the top 2 results based on the tomato.rating
data
{
"title": "Once Upon a Time in the West",
"year": 1968,
"rated": "PG-13",
"runtime": 175,
"countries": [
"Italy",
"USA",
"Spain"
],
"genres": [
"Western"
],
"director": "Sergio Leone",
"writers": [
"Sergio Donati",
"Sergio Leone",
"Dario Argento",
"Bernardo Bertolucci",
"Sergio Leone"
],
"actors": [
"Claudia Cardinale",
"Henry Fonda",
"Jason Robards",
"Charles Bronson"
],
"plot": "Epic story of a mysterious stranger with a harmonica who joins forces with a notorious desperado to protect a beautiful widow from a ruthless assassin working for the railroad.",
"poster": "http://ia.media-imdb.com/images/M/MV5BMTEyODQzNDkzNjVeQTJeQWpwZ15BbWU4MDgyODk1NDEx._V1_SX300.jpg",
"imdb": {
"id": "tt0064116",
"rating": 8.6,
"votes": 201283
},
"tomato": {
"meter": 98,
"image": "certified",
"rating": 9,
"reviews": 54,
"fresh": 53,
"consensus": "A landmark Sergio Leone spaghetti western masterpiece featuring a classic Morricone score.",
"userMeter": 95,
"userRating": 4.3,
"userReviews": 64006
},
"metacritic": 80,
"awards": {
"wins": 4,
"nominations": 5,
"text": "4 wins \u0026 5 nominations."
},
"type": "movie"
},
{
"title": "A Million Ways to Die in the West",
"year": 2014,
"rated": "R",
"runtime": 116,
"countries": [
"USA"
],
"genres": [
"Comedy",
"Western"
],
"director": "Seth MacFarlane",
"writers": [
"Seth MacFarlane",
"Alec Sulkin",
"Wellesley Wild"
],
"actors": [
"Seth MacFarlane",
"Charlize Theron",
"Amanda Seyfried",
"Liam Neeson"
],
"plot": "As a cowardly farmer begins to fall for the mysterious new woman in town, he must put his new-found courage to the test when her husband, a notorious gun-slinger, announces his arrival.",
"poster": "http://ia.media-imdb.com/images/M/MV5BMTQ0NDcyNjg0MV5BMl5BanBnXkFtZTgwMzk4NTA4MTE#._V1_SX300.jpg",
"imdb": {
"id": "tt2557490",
"rating": 6.1,
"votes": 126592
},
"tomato": {
"meter": 33,
"image": "rotten",
"rating": 4.9,
"reviews": 188,
"fresh": 62,
"consensus": "While it offers a few laughs and boasts a talented cast, Seth MacFarlane's overlong, aimless A Million Ways to Die in the West is a disappointingly scattershot affair.",
"userMeter": 40,
"userRating": 3,
"userReviews": 62945
},
"metacritic": 44,
"awards": {
"wins": 0,
"nominations": 6,
"text": "6 nominations."
},
"type": "movie"
},
{
"title": "Wild Wild West",
"year": 1999,
"rated": "PG-13",
"runtime": 106,
"countries": [
"USA"
],
"genres": [
"Action",
"Western",
"Comedy"
],
"director": "Barry Sonnenfeld",
"writers": [
"Jim Thomas",
"John Thomas",
"S.S. Wilson",
"Brent Maddock",
"Jeffrey Price",
"Peter S. Seaman"
],
"actors": [
"Will Smith",
"Kevin Kline",
"Kenneth Branagh",
"Salma Hayek"
],
"plot": "The two best hired guns in the West must save President Grant from the clutches of a nineteenth-century inventor-villain.",
"poster": "http://ia.media-imdb.com/images/M/MV5BNDI5NDk5MjgxMl5BMl5BanBnXkFtZTcwNjI1MTUyMQ##._V1_SX300.jpg",
"imdb": {
"id": "tt0120891",
"rating": 4.8,
"votes": 124558
},
"tomato": {
"meter": 17,
"image": "rotten",
"rating": 4.1,
"reviews": 130,
"fresh": 22,
"consensus": "Bombastic, manic, and largely laugh-free, Wild Wild West is a bizarre misfire in which greater care was lavished upon the special effects than on the script.",
"userMeter": 28,
"userRating": 2.7,
"userReviews": 463740
},
"metacritic": 38,
"awards": {
"wins": 10,
"nominations": 11,
"text": "10 wins \u0026 11 nominations."
},
"type": "movie"
},
{
"title": "West Side Story",
"year": 1961,
"rated": "UNRATED",
"runtime": 152,
"countries": [
"USA"
],
"genres": [
"Crime",
"Drama",
"Musical"
],
"director": "Jerome Robbins, Robert Wise",
"writers": [
"Ernest Lehman",
"Arthur Laurents",
"Jerome Robbins"
],
"actors": [
"Natalie Wood",
"Richard Beymer",
"Russ Tamblyn",
"Rita Moreno"
],
"plot": "Two youngsters from rival New York City gangs fall in love, but tensions between their respective friends build toward tragedy.",
"poster": "http://ia.media-imdb.com/images/M/MV5BMTM0NDAxOTI5MF5BMl5BanBnXkFtZTcwNjI4Mjg3NA##._V1_SX300.jpg",
"imdb": {
"id": "tt0055614",
"rating": 7.6,
"votes": 67824
},
"awards": {
"wins": 18,
"nominations": 11,
"text": "Won 10 Oscars. Another 18 wins \u0026 11 nominations."
},
"type": "movie"
},
{
"title": "Slow West",
"year": 2015,
"rated": "R",
"runtime": 84,
"countries": [
"UK",
"New Zealand"
],
"genres": [
"Action",
"Thriller",
"Western"
],
"director": "John Maclean",
"writers": [
"John Maclean"
],
"actors": [
"Kodi Smit-McPhee",
"Michael Fassbender",
"Ben Mendelsohn",
"Aorere Paki"
],
"plot": "A young Scottish man travels across America in pursuit of the woman he loves, attracting the attention of an outlaw who is willing to serve as a guide.",
"poster": "http://ia.media-imdb.com/images/M/MV5BNTYxNDA5ODk5NF5BMl5BanBnXkFtZTgwNzMwMzIwNTE#._V1_SX300.jpg",
"imdb": {
"id": "tt3205376",
"rating": 7,
"votes": 19101
},
"tomato": {
"meter": 92,
"image": "certified",
"rating": 7.5,
"reviews": 115,
"fresh": 106,
"consensus": "Slow West serves as an impressive calling card for first-time writer-director John M. Maclean -- and offers an inventive treat for fans of the Western.",
"userMeter": 75,
"userRating": 3.7,
"userReviews": 9850
},
"metacritic": 72,
"awards": {
"wins": 2,
"nominations": 9,
"text": "2 wins \u0026 9 nominations."
},
"type": "movie"
},
{
"title": "An American Tail: Fievel Goes West",
"year": 1991,
"rated": "G",
"runtime": 75,
"countries": [
"USA"
],
"genres": [
"Animation",
"Adventure",
"Family"
],
"director": "Phil Nibbelink, Simon Wells",
"writers": [
"Flint Dille",
"Charles Swenson",
"David Kirschner"
],
"actors": [
"Phillip Glasser",
"James Stewart",
"Erica Yohn",
"Cathy Cavadini"
],
"plot": "A family of Emigre mice decide to move out to the west, unaware that they are falling into a trap perpetrated by a smooth talking cat.",
"poster": "http://ia.media-imdb.com/images/M/MV5BMTYzODMxNTUyNF5BMl5BanBnXkFtZTcwMTAwMzQyMQ##._V1_SX300.jpg",
"imdb": {
"id": "tt0101329",
"rating": 6.4,
"votes": 16013
},
"awards": {
"wins": 0,
"nominations": 0,
"text": ""
},
"type": "movie"
},
tomato.rating get
db.MovieData.aggregate([
{ "$unwind": "$tomato" },
{ "$sort": { "tomato.meter": -1 } },
{ "$limit": 2 },
{"$project": {title:1, "tomato.meter":1}},
])
imbd
db.MovieData.aggregate([
{ "$sort": { "imdb.rating": -1 } },
{ "$limit": 2 },
{"$project": {title:1, "imdb.rating":1}},
])
Meta critic
db.MovieData.aggregate([
{ "$sort": { "metacritic": -1 } },
{ "$limit": 2 },
{"$project": {title:1, "metacritic":1}},
])
These sort of "limitted" operations are perfectly suited to $facet:
db.MovieData.aggregate([
{ "$facet": {
"tomato": [
{ "$sort": { "tomato.meter": -1 } },
{ "$limit": 2 },
{"$project": {title:1, "tomato.meter":1}},
],
"imdb": [
{ "$sort": { "imdb.rating": -1 } },
{ "$limit": 2 },
{"$project": {title:1, "imdb.rating":1}},
],
"metacrtic": [
{ "$sort": { "metacritic": -1 } },
{ "$limit": 2 },
{"$project": {title:1, "metacritic":1}},
]
}}
])
Returns from the data in the question:
{
"tomato" : [
{
"_id" : ObjectId("5c80979542dd84d91e5547d9"),
"title" : "Once Upon a Time in the West",
"tomato" : {
"meter" : 98
}
},
{
"_id" : ObjectId("5c80979542dd84d91e5547dd"),
"title" : "Slow West",
"tomato" : {
"meter" : 92
}
}
],
"imdb" : [
{
"_id" : ObjectId("5c80979542dd84d91e5547d9"),
"title" : "Once Upon a Time in the West",
"imdb" : {
"rating" : 8.6
}
},
{
"_id" : ObjectId("5c80979542dd84d91e5547dc"),
"title" : "West Side Story",
"imdb" : {
"rating" : 7.6
}
}
],
"metacrtic" : [
{
"_id" : ObjectId("5c80979542dd84d91e5547d9"),
"title" : "Once Upon a Time in the West",
"metacritic" : 80
},
{
"_id" : ObjectId("5c80979542dd84d91e5547dd"),
"title" : "Slow West",
"metacritic" : 72
}
]
}
As long as the results are "small" then it's perfectly okay to run multiple pipelines this way.
If results are large it would be better to run independent queries and preferably in parallel ( i.e under Promise.all() for NodeJS for example ) and combine results ( as the Promise.all() example would ).
Whilst this effectively requires more database connections, that additional overhead is typically negated by the parallel processing. And of course means combined results ( especially when processed from cursors ) would not cause the BSON limit on a response to be broken.
NOTE: tomato is an Object and not an Array, so you don't use $unwind
There are 3 master collection of category , subcategory and criteria each, i will be building framework with any possible combination of category , subcategory and criteria which will be stored as below-
framework document is added below having list of criteriaconfig as embedded object which further have single object of category , subcategory and criteria. you can refer criteriaconfig as link table that u call in mysql.
[
{
"id": "592bc3059f3ad715002b2331",
"name": "Framework1",
"description": "framework 1 for testing",
"criteriaConfigs": [
{
"id": "592bc3059f3ad715002b232f",
"category": {
"id": "591c2f5faa187956b2d0fb39",
"name": "category1",
"description": "category1",
"deleted": false,
"createdDate": 1495019359558
},
"subCategory": {
"id": "591c2f5faa187956b2d0fb83",
"name": "subCat1",
"description": "subCat1"
},
"criteria": {
"id": "591c2f5faa187956b2d0fbad",
"name": "criteria1",
"measure": "Action"
}
},
{
"id": "592bc3059f3ad715002b232e",
"category": {
"id": "591c2f5faa187956b2d0fb37",
"name": "Process",
"description": "Enagagement"
},
"subCategory": {
"id": "591c2f5faa187956b2d0fb81",
"name": "COMM / BRANDING",
"description": "COMM / BRANDING"
},
"criteria": {
"id": "591c2f5faa187956b2d0fba9",
"name": "Company representative forgets about customer on hold",
"measure": ""
}
} ]
},
{
"id": "592bc3059f3ad715002b2332",
"name": "Framework2",
"description": "framework 2 for testing",
"criteriaConfigs": [
{
"id": "592bc3059f3ad715002b232f",
"category": {
"id": "591c2f5faa187956b2d0fb39",
"name": "category1",
"description": "category1"
},
"subCategory": {
"id": "591c2f5faa187956b2d0fb83",
"name": "subCat1",
"description": "subCat1"
},
"criteria": {
"id": "591c2f5faa187956b2d0fbad",
"name": "criteria1",
"measure": "Action"
}
}
]
}
]
i need a view containing framework that will contain all list of category and inside category there will be list of added subcategory and inside subcategory will have list of criteria for single framework.
expected result -
[
{
"id": "f1",
"name": "Framework1",
"description": "framework 1 for testing",
"categories": [
{
"id": "c2",
"name": "category2",
"description": "category2",
"subCategories": [
{
"id": "sb1",
"name": "subCat1",
"description": "subCat1",
"criterias": [
{
"id": "cr1",
"name": "criteria1",
"measure": "Action"
},
{
"id": "cr2",
"name": "criteria2",
"measure": "Action"
},
{
"id": "cr3",
"name": "criteria3",
"measure": "Action"
}]
},
{
"id": "sb2",
"name": "subCat2",
"description": "subCat2",
"criterias": [
{
"id": "cr1",
"name": "criteria1",
"measure": "Action"
},
{
"id": "cr4",
"name": "criteria4",
"measure": "Action"
}]
}]
},
{
"id": "c1",
"name": "category1",
"description": "category1",
"subCategories": [
{
"id": "sb3",
"name": "subCat3",
"description": "subCat3",
"criterias": [
{
"id": "cr1",
"name": "criteria1",
"measure": "Action"
},
{
"id": "cr2",
"name": "criteria2",
"measure": "Action"
}
]},
{
"id": "sb2",
"name": "subCat2",
"description": "subCat2",
"criterias": [
{
"id": "cr1",
"name": "criteria1",
"measure": "Action"
},
{
"id": "cr4",
"name": "criteria4",
"measure": "Action"
}]
}
]
}]
},
{
"id": "f2",
"name": "Framework2",
"description": "framework 2 for testing",
"categories": [
{
"id": "c2",
"name": "category2",
"description": "category2",
"subCategories": [
{
"id": "sb4",
"name": "subCat5",
"description": "subCat5",
"criterias": [
{
"id": "cr1",
"name": "criteria1",
"measure": "Action"
},
{
"id": "cr3",
"name": "criteria3",
"measure": "Action"
}]
},
{
"id": "sb2",
"name": "subCat2",
"description": "subCat2",
"criterias": [
{
"id": "cr1",
"name": "criteria1",
"measure": "Action"
},
{
"id": "cr4",
"name": "criteria4",
"measure": "Action"
}]
}]
},
{
"id": "c1",
"name": "category1",
"description": "category1",
"subCategories": [
{
"id": "sb3",
"name": "subCat3",
"description": "subCat3",
"criterias": [
{
"id": "cr1",
"name": "criteria1",
"measure": "Action"
},
{
"id": "cr2",
"name": "criteria2",
"measure": "Action"
}
]},
{
"id": "sb2",
"name": "subCat2",
"description": "subCat2",
"criterias": [
{
"id": "cr1",
"name": "criteria1",
"measure": "Action"
},
{
"id": "cr4",
"name": "criteria4",
"measure": "Action"
}]
}
]
}]
}
]
Note - Category document doesn't have any reference to subcategory and same way subcategory doesn't have any reference to criteria object currently as they are master data and are generic , framework is created with their combination dynamically.
If you want to try to do all the work in the aggregation, you could group first by subcategory, then by category like:
db.collection.aggregate([
{$unwind:"$criteriaConfigs"},
{$project:{
_id:0,
category:"$criteriaConfigs.category",
subCategory:"$criteriaConfigs.subCategory",
criteria:"$criteriaConfigs.criteria"
}},
{$group:{
_id:{"category":"$category","subCategory":"$subCategory"},
criteria:{$addToSet:"$criteria"}
}},
{$group:{
_id:{"category":"$_id.category"},
subCategories:{$addToSet:{subCategory:"$_id.subCategory",
criteria:"$criteria"}}
}},
{$project:{
_id:0,category:"$_id.category",
subCategories:"$subCategories"
}}
])
Depending on how you plan to us the return data, it may be more efficient to return each unique combination:
db.collection.aggregate([
{$unwind:"$criteriaConfigs"},
{$group:{
_id:{
category:"$criteriaConfigs.category.name",
subCategory:"$criteriaConfigs.subCategory.name",
criteria:"$criteriaConfigs.criteria.name"
}
}},
{$project:{
_id:0,
category:"$_id.category",
subCategory:"$_id.subCategory",
criteria:"$_id.criteria"
}}
])
I'm not sure from your question what shape you are expecting the return data to have, so you may need to adjust for that.
I am working on mongoDB with Laravel using jenssegers . and i am trying to get
documents on sorting based on layout.price.
Is this possible in mongodb with laravel. ?
I am using limit and skip for pagination , so i have to get orderBy or sort direct from Database.
[{
"title": "I am first document",
"design": "mango",
"description": "Loremipsum",
"dimension": [
{
"id": "542549383d1784901000002c"
}
],
"layout": [
{
"id": "542411813d17849810000029",
"price": NumberInt(69000)
}, {
"id": "542411813d17849810000030",
"price": NumberInt(2000)
}
],
"images": [
"uploads/sofa/QRSTU695a6_0.png"
],
"product_type": NumberInt(1),
"updated_at": ISODate("2014-10-08T08:47:26.0Z"),
"created_at": ISODate("2014-09-29T11:13:52.0Z")
},
{
"title": "I am second document",
"design": "mango2",
"description": "Loremipsum",
"dimension": [
{
"id": "542549383d1784901000002d"
}
],
"layout": [
{
"id": "542411813d17849810000031",
"price": NumberInt(80000)
}, {
"id": "542411813d17849810000032",
"price": NumberInt(27000)
}
],
"images": [
"uploads/sofa/QRSTU695a6_0.png"
],
"product_type": NumberInt(1),
"updated_at": ISODate("2014-10-08T08:47:26.0Z"),
"created_at": ISODate("2014-09-29T11:13:52.0Z")
}]