I am using mongoose and node and I am trying to paginate data from sub-documents. I am able to limit subdocuments, but not skip them.
The versions I am using are:
Mongo 3.0.0
Node 0.10.33
Mongoose 3.9.7
The Data
[{
"name" : "Ranger Table",
"_id" : ObjectId("550234d3d06039d507d238d8"),
"body" : [
{
"name" : "Jason",
"colour" : "Red",
"animal" : "T-rex",
"_id" : ObjectId("550234d3d06039d507d238de")
},
{
"name" : "Billy",
"colour" : "Blue",
"animal" : "Triceratops",
"_id" : ObjectId("550234d3d06039d507d238dd")
},
{
"name" : "Zach",
"colour" : "Black",
"animal" : "Mastadon",
"_id" : ObjectId("550234d3d06039d507d238dc")
},
{
"name" : "Tommy",
"colour" : "Green",
"animal" : "Dragon"
"_id" : ObjectId("550234d3d06039d507d238d9")
}
]
},{
"name" : "Bot Table",
"_id" : ObjectId("5502d205184cd74033f64e6b"),
"body" : [
{
"name" : "Optimus",
"team" : "Autobots",
"class" : "Leader",
"_id" : ObjectId("550234d3d06039d507d238d9")
},
{
"name" : "Bumblebee",
"team" : "Autobots",
"class" : "Scout",
"_id" : ObjectId("550234d3d06039d507d238da")
},
{
"name" : "Astrotrain",
"team" : "Decepticons",
"class" : "Transport",
"_id" : ObjectId("550234d3d06039d507d238db")
}
]
}]
The Code
var BodySchema = new Schema({random: String},{strict:false});
var FeedSchema = new Schema({
name: String,
body:[BodySchema]
});
var feed = mongoose.model('Feed', FeedSchema);
feed.find({_id:'550234d3d06039d507d238d8'})
.populate({
"path":"body",
"options":{
limit:2, //This works fine
skip:2 //This doesn't work
}
})
.exec(function(err, result){
if(err){return(res.send(500, err))}
res.send(result);
});
The Result
The above code DOES limit the number of "body" sub-documents to 2, but doesn't skip any.
The code above returns this:
{
"name" : "Ranger Table",
"_id" : ObjectId("550234d3d06039d507d238d8"),
"body" : [
{
"name" : "Jason",
"colour" : "Red",
"animal" : "T-rex",
"_id" : ObjectId("550234d3d06039d507d238de")
},
{
"name" : "Billy",
"colour" : "Blue",
"animal" : "Triceratops",
"_id" : ObjectId("550234d3d06039d507d238dd")
}
]
}
But it should return this:
{
"name" : "Ranger Table",
"_id" : ObjectId("550234d3d06039d507d238d8"),
"body" : [
{
"name" : "Zach",
"colour" : "Black",
"animal" : "Mastadon",
"_id" : ObjectId("550234d3d06039d507d238dc")
},
{
"name" : "Tommy",
"colour" : "Green",
"animal" : "Dragon"
"_id" : ObjectId("550234d3d06039d507d238d9")
}
]
}
The solution that I found was to use aggregate and specify the name of the subdocument with $unwind.
http://docs.mongodb.org/manual/reference/operator/aggregation/
feed.aggregate([
{'$match':{_id:id('550234d3d06039d507d238d8')}},
{'$unwind':'$body'},
{'$skip':2},
{'$limit':2},
], function(err, result){
if(err){return(res.send(500, err))}
res.send(result);
});
Related
I just wanted to fetch that data which coming from this https://food-ordring-af14d-default-rtdb.firebaseio.com/order the data is in the form of JSON and it looks like that
{
"-MzJLd0sSssh9tbJbjUS" : {
"orderDetails" : [ {
"amount" : 4,
"id" : "m1",
"name" : "Shushi",
"price" : 22.99
}, {
"amount" : 3,
"id" : "m2",
"name" : "Schnitzel",
"price" : 16.5
} ],
"user" : {
"address" : "A-132 shiv vihar,rishal garden,Nangloi",
"city" : "New delhi",
"name" : "Bhupender Sharma",
"postal" : "110041"
}
},
"-MzJOf_52xhRQi3izTRV" : {
"orderDetails" : [ {
"amount" : 2,
"id" : "m3",
"name" : "Barbecue Burger",
"price" : 12.99
}, {
"amount" : 2,
"id" : "m4",
"name" : "Green Bowl",
"price" : 18.99
} ],
"user" : {
"address" : "Nangloi",
"city" : "New delhi",
"name" : "ANkit",
"postal" : "445575"
}
}
}
Try this code .. here some example
const fetchdata = async()=>{
const response = await fetch('https://jsonplaceholder.typicode.com/todos')
const jdata = await response.json()
console.log(jdata)
}
fetchdata()
I need to make a query where it matches a specific value of an array. Not all the values of the array but only one. I know in mongo there is a $in operator so you can match 1 value of the array.
I have written my code something like this:
const getSearch = async (req,res) => {
try{
//query = { establishment: { name: "foodtruck" }, configuration: { name: "lineal" } }
console.log(query)
let doesExist = await Kitchen.find({ "establishment": { "name": { "$in": ["foodtruck","salon"] } }})
console.log(doesExist)
}catch(err){
throw err
}
}
In my local mongo i have different objects that matches the establishment name. Here they are:
db.kitchens.find()
{ "_id" : ObjectId("6084ca4c49ddab30473a7396"), "anafes" : { "quantity" : "1" }, "norms" : [ "norm5", "norm4" ], "availableDays" : [ "4/26/2021", "4/27/2021", "4/28/2021", "4/29/2021", "4/30/2021", "5/1/2021", "5/10/2021", "5/11/2021", "5/12/2021", "5/13/2021", "5/14/2021", "5/15/2021", "5/16/2021", "5/17/2021", "5/18/2021", "5/19/2021", "5/2/2021", "5/20/2021", "5/21/2021", "5/22/2021", "5/3/2021", "5/4/2021", "5/5/2021", "5/6/2021", "5/7/2021", "5/8/2021", "5/9/2021" ], "created_at" : ISODate("2021-04-25T01:26:29.542Z"), "updated_at" : ISODate("2021-04-25T01:26:29.542Z"), "deleted_at" : null, "establishment" : { "name" : "delivery" }, "dimensions" : { "name" : "40" }, "configuration" : { "name" : "lineal" }, "pictures" : [ { "_id" : ObjectId("6084ca4c49ddab30473a7397"), "url" : "https://hood-bucket-2021.s3.sa-east-1.amazonaws.com/images/1619315274721.jpg" } ], "timePrices" : [ { "_id" : ObjectId("6084ca4c49ddab30473a7398"), "time" : "perWeek", "price" : "5000" } ], "check_in" : { "from" : "00:00", "to" : "00:00" }, "check_out" : { "from" : "00:00", "to" : "00:00" }, "ovens" : { "name" : "convection", "brand" : "adidas" }, "location" : { "city" : "Buenos Aires", "province" : "Buenos Aires", "street" : "Teodoro Garcia", "number" : "1930", "coords" : [ { "_id" : ObjectId("6084ca4c49ddab30473a7399"), "lat" : "-34.5650491", "lng" : "-58.4415115" } ], "floor" : "9", "postal" : 1426 }, "type_of_time" : [ { "_id" : ObjectId("6084ca4c49ddab30473a739a"), "time" : "perWeek" } ], "host" : ObjectId("605f4e36d8281726d9be3ad3"), "__v" : 0 }
{ "_id" : ObjectId("6089f8a7bda5898d50876791"), "anafes" : { "quantity" : "1" }, "norms" : [ "norm2", "norm3", "norm8" ], "availableDays" : [ "4/30/2021", "5/1/2021", "5/10/2021", "5/11/2021", "5/12/2021", "5/13/2021", "5/14/2021", "5/15/2021", "5/16/2021", "5/17/2021", "5/18/2021", "5/19/2021", "5/2/2021", "5/20/2021", "5/21/2021", "5/22/2021", "5/23/2021", "5/24/2021", "5/25/2021", "5/26/2021", "5/27/2021", "5/28/2021", "5/29/2021", "5/3/2021", "5/30/2021", "5/31/2021", "5/4/2021", "5/5/2021", "5/6/2021", "5/7/2021", "5/8/2021", "5/9/2021", "7/1/2021", "7/10/2021", "7/11/2021", "7/12/2021", "7/13/2021", "7/14/2021", "7/15/2021", "7/16/2021", "7/17/2021", "7/18/2021", "7/19/2021", "7/2/2021", "7/20/2021", "7/21/2021", "7/22/2021", "7/23/2021", "7/24/2021", "7/25/2021", "7/26/2021", "7/27/2021", "7/28/2021", "7/29/2021", "7/3/2021", "7/30/2021", "7/31/2021", "7/4/2021", "7/5/2021", "7/6/2021", "7/7/2021", "7/8/2021", "7/9/2021" ], "created_at" : ISODate("2021-04-28T23:56:46.101Z"), "updated_at" : ISODate("2021-04-28T23:56:46.102Z"), "deleted_at" : null, "establishment" : { "name" : "foodtruck" }, "dimensions" : { "name" : "50" }, "configuration" : { "name" : "general" }, "pictures" : [ { "_id" : ObjectId("6089f8a7bda5898d50876792"), "url" : "https://hood-bucket-2021.s3.sa-east-1.amazonaws.com/images/1619654809186.jpg" }, { "_id" : ObjectId("6089f8a7bda5898d50876793"), "url" : "https://hood-bucket-2021.s3.sa-east-1.amazonaws.com/images/1619654809259.jpg" } ], "timePrices" : [ { "_id" : ObjectId("6089f8a7bda5898d50876794"), "time" : "perDay", "price" : "10000" } ], "check_in" : { "from" : "10:00", "to" : "12:00" }, "check_out" : { "from" : "15:00", "to" : "17:00" }, "ovens" : { "name" : "static", "brand" : "adidas" }, "location" : { "city" : "buenos aires", "coords" : [ { "_id" : ObjectId("6089f8a7bda5898d50876795"), "lat" : "-34.5659098", "lng" : "-58.43880350000001" } ], "province" : "buenos aires", "street" : "Olleros", "number" : "1870", "floor" : "4", "postal" : 1426 }, "type_of_time" : [ { "_id" : ObjectId("6089f8a7bda5898d50876796"), "time" : "perDay" } ], "host" : ObjectId("605f4e36d8281726d9be3ad3"), "__v" : 0 }
{ "_id" : ObjectId("608a09e29eda52a6cdc7d663"), "anafes" : { "quantity" : "1" }, "norms" : [ "norm1", "norm2", "norm4" ], "availableDays" : [ "4/30/2021", "6/1/2021", "6/10/2021", "6/11/2021", "6/12/2021", "6/13/2021", "6/14/2021", "6/15/2021", "6/16/2021", "6/17/2021", "6/18/2021", "6/19/2021", "6/2/2021", "6/20/2021", "6/21/2021", "6/22/2021", "6/23/2021", "6/24/2021", "6/25/2021", "6/26/2021", "6/27/2021", "6/28/2021", "6/29/2021", "6/3/2021", "6/30/2021", "6/4/2021", "6/5/2021", "6/6/2021", "6/7/2021", "6/8/2021", "6/9/2021" ], "created_at" : ISODate("2021-04-29T00:47:45.376Z"), "updated_at" : ISODate("2021-04-29T00:47:45.376Z"), "deleted_at" : null, "establishment" : { "name" : "foodtruck" }, "dimensions" : { "name" : "50" }, "configuration" : { "name" : "lineal" }, "pictures" : [ { "_id" : ObjectId("608a09e29eda52a6cdc7d664"), "url" : "https://hood-bucket-2021.s3.sa-east-1.amazonaws.com/images/1619659217736.jpg" }, { "_id" : ObjectId("608a09e29eda52a6cdc7d665"), "url" : "https://hood-bucket-2021.s3.sa-east-1.amazonaws.com/images/1619659217747.jpg" }, { "_id" : ObjectId("608a09e29eda52a6cdc7d666"), "url" : "https://hood-bucket-2021.s3.sa-east-1.amazonaws.com/images/1619659217668.jpg" } ], "timePrices" : [ { "_id" : ObjectId("608a09e29eda52a6cdc7d667"), "time" : "perDay", "price" : "5000" }, { "_id" : ObjectId("608a09e29eda52a6cdc7d668"), "time" : "perWeek", "price" : "15000" } ], "check_in" : { "from" : "07:00", "to" : "08:00" }, "check_out" : { "from" : "14:00", "to" : "20:00" }, "ovens" : { "name" : "convection", "brand" : "super", "model" : "adibas" }, "location" : { "city" : "BUenos aires", "coords" : [ { "_id" : ObjectId("608a09e29eda52a6cdc7d669"), "lat" : "-34.5793959", "lng" : "-58.40673389999999" } ], "province" : "Buenos aires", "street" : "Avenida del libertador", "number" : "2550", "floor" : "10", "postal" : 1426 }, "type_of_time" : [ { "_id" : ObjectId("608a09e29eda52a6cdc7d66a"), "time" : "perDay" }, { "_id" : ObjectId("608a09e29eda52a6cdc7d66b"), "time" : "perWeek" } ], "host" : ObjectId("605f4e36d8281726d9be3ad3"), "__v" : 0 }
But when I run this query:
let doesExist = await Kitchen.find({ "establishment": { "name": { "$in": ["foodtruck","salon"] } }})
it does not match anything, but if I run this query:
let doesExist = await Kitchen.find({ "establishment": { "name": "foodtruck" }})
It does match. I don't understand what I am doing wrong, or why the $in operator is not.
working.
Can someone help me?????????
let doesExist = await Kitchen.find({"establishment.name": {"$in": ["foodtruck","salon"]}})
I have data from mongodb like this from one collection.
/* 1 */
{
"_id" : ObjectId("5be94355f220b62c7449dc0f"),
"districts" : [
{
"name" : "NORTH AND MIDDLE",
"code" : 632.0
},
{
"name" : "EAST",
"code" : 603.0
},
{
"name" : "SOUTH",
"code" : 602.0
}
],
"state" : "ISLANDS"
}
/* 2 */
{
"_id" : ObjectId("5be94355f220b62c7441dc04"),
"districts" : [
{
"name" : "Apple",
"code" : 512.0
},
{
"name" : "Ball",
"code" : 522.0
}
],
"state" : "GOLD"
}
/* 3 */
{
"_id" : ObjectId("5eee07816a011d391a45178"),
"districts" : [
{
"name" : "DAM",
"code" : 478.0
},
{
"name" : "DEN",
"code" : 481.0
},
{
"name" : "DOG AND CAT",
"code" : 461.0
}
],
"state" : "THE NAGAR AND HAVELI"
}
I was given an excel sheet like below as shown with no other information only 2 columns
My work is to add "Short Name of District" for all districts.
I tried below method
var tc = [
"NORTH AND MIDDLE",
"EAST",
"SOUTH",
"Apple",
"Ball ",
"DAM ",
"DEN ",
"DOG AND CAT"
]
db.dummy.find({"districts.name":{$in:tc}}).forEach(x => {
x["districts"].forEach( y => {
if (
y.name == "NORTH AND MIDDLE" ){
y.short_name = "NAM"
}
if (
y.name == "EAST" ){
y.short_name = "ET"
}
if (
y.name == "SOUTH" ){
y.short_name = "ST"
}
})
})
I got the result
/* 1 */
{
"_id" : ObjectId("5be94355f220b62c7449dc0f"),
"districts" : [
{
"name" : "NORTH AND MIDDLE",
"code" : 632.0,
"short_name" : "NAM"
},
{
"name" : "EAST",
"code" : 603.0,
"short_name" : "ET"
},
{
"name" : "SOUTH",
"code" : 602.0,
"short_name" : "ST"
}
],
"state" : "ISLANDS"
}
/* 2 */
{
"_id" : ObjectId("5be94355f220b62c7441dc04"),
"districts" : [
{
"name" : "Apple",
"code" : 512.0,
"short_name" : "Al"
},
{
"name" : "Ball",
"code" : 522.0
"short_name" : "BA"
}
],
"state" : "GOLD"
}
/* 3 */
{
"_id" : ObjectId("5eee07816a011d391a45178"),
"districts" : [
{
"name" : "DAM",
"code" : 478.0,
"short_name" : "DA"
},
{
"name" : "DEN",
"code" : 481.0,
"short_name" : "DN"
},
{
"name" : "DOG AND CAT",
"code" : 461.0
"short_name" : "DAC"
}
],
"state" : "THE NAGAR AND HAVELI"
}
Is this is the only method ??
like using if loop for all districts or any other methods are there like using mongodb aggregate or any other javascript methods. It will be helpful if other methods are there as it will be problem to use if loop when there is 730 districts are there. I dont have experience in working with aggregate frameworks so i thought anyone might know other method.
You may write a mapping:
const districtNameToShort = {
'NORTH AND MIDDLE': 'NAM',
'EAST': 'ET',
...
}
Then in your forEach
const districtNameToShort = {
'NORTH AND MIDDLE': 'NAM',
'EAST': 'ET'
}
db.dummy.find().forEach(x => {
db.dummy.update(
{_id : x._id},
{$set: {
districts: x.districts.map(district => {
district.short_name = districtNameToShort[district.name] || district.name
return district
})
}}
)
})
I have some data (let's call it logs) in mongodb, let's say like this:
{
name: String,
category_id: String
}
Each category has parent_id. What I want is to get as up tree as possible, to the first parent and get all parents for each item of data I get from so called logs.
What I thought of first: in the controller to get all projects, then recursively get it's all parents. It'll probably works, but it seems tedious and wrong.
There is probably a better thing to do on the model itself, like a static method.
So, my question is how would you do this with mongodb? I know there are aggregations, and I used them a couple of times, but I can see how to use them if by certain field with the certain value. But here you get one project, get the next by it's parent_id and so on and so on.
You have to look at $graphLookup aggregation stage. Provide a set of relevant data for more help.
EDIT : here an example :
---DATA---
#logs collection
db.logs.find({});
{
"_id" : ObjectId("5b4f2970d42ef3178d108e86"),
"name" : "01",
"category" : "cat1"
}
{
"_id" : ObjectId("5b4f2981d42ef3178d108e87"),
"name" : "02",
"category" : "cat1"
}
{
"_id" : ObjectId("5b4f298ad42ef3178d108e88"),
"name" : "03",
"category" : "cat2"
}
{
"_id" : ObjectId("5b4f2997d42ef3178d108e89"),
"name" : "04",
"category" : "cat2"
}
{
"_id" : ObjectId("5b4f29bed42ef3178d108e8a"),
"name" : "015",
"category" : "cat10"
}
#categories collection
db.categories.find({});
{
"_id" : "cat1",
"parent_id" : "cat2"
}
{
"_id" : "cat2",
"parent_id" : "cat10"
}
{
"_id" : "cat10"
}
---AGGREGATION QUERY---
db.logs.aggregate(
[
{
$graphLookup: {
from: "categories",
startWith: "$category", // connectToField value(s) that recursive search starts with
connectFromField: "parent_id",
connectToField: "_id",
as: "related_categories",
maxDepth: 10, // optional
depthField: "depthField" // optional - name of field in output documents
}
},
],
);
---OUTPUT---
{
"_id" : ObjectId("5b4f2970d42ef3178d108e86"),
"name" : "01",
"category" : "cat1",
"related_categories" : [
{
"_id" : "cat10",
"depthField" : NumberLong(2)
},
{
"_id" : "cat2",
"parent_id" : "cat10",
"depthField" : NumberLong(1)
},
{
"_id" : "cat1",
"parent_id" : "cat2",
"depthField" : NumberLong(0)
}
]
}
{
"_id" : ObjectId("5b4f2981d42ef3178d108e87"),
"name" : "02",
"category" : "cat1",
"related_categories" : [
{
"_id" : "cat10",
"depthField" : NumberLong(2)
},
{
"_id" : "cat2",
"parent_id" : "cat10",
"depthField" : NumberLong(1)
},
{
"_id" : "cat1",
"parent_id" : "cat2",
"depthField" : NumberLong(0)
}
]
}
{
"_id" : ObjectId("5b4f298ad42ef3178d108e88"),
"name" : "03",
"category" : "cat2",
"related_categories" : [
{
"_id" : "cat10",
"depthField" : NumberLong(1)
},
{
"_id" : "cat2",
"parent_id" : "cat10",
"depthField" : NumberLong(0)
}
]
}
{
"_id" : ObjectId("5b4f2997d42ef3178d108e89"),
"name" : "04",
"category" : "cat2",
"related_categories" : [
{
"_id" : "cat10",
"depthField" : NumberLong(1)
},
{
"_id" : "cat2",
"parent_id" : "cat10",
"depthField" : NumberLong(0)
}
]
}
{
"_id" : ObjectId("5b4f29bed42ef3178d108e8a"),
"name" : "015",
"category" : "cat10",
"related_categories" : [
{
"_id" : "cat10",
"depthField" : NumberLong(0)
}
]
}
I'm able to do
db.getCollection('comps').find({"stats.cat3.detail.name" : "Friendlyness"})`
This shows the proper docs the have a name of "Friendlyness" in the detail array.
I wanted to change "Friendlyness" to "friendliness"
I tried :
db.getCollection('comps').update(
{"stats.cat3.detail.name" : "Friendlyness"},
{$set : {"stats.cat3.detail.name" : "Friendliness"} }
)
and got errors like
" cannot use the part (stats of stats.cat3.detail.name) to traverse the element ({stats: [ { cat3: ...."
I tried putting in position operators "$" all over the update object property. but still get errors.
sample data:
{
"_id" : ObjectId("58d94c441eb9e52454932db6"),
"desc" : "Manufacturer of a wide range of consumer electronics products including audio, video, communications, and computer systems.",
"source" : "alexa",
"category" : "Consumer Electronics",
"name" : "comp1.com",
"__v" : 0,
"stats" : [
{
"cat1" : {
"detail" : [
{
"value" : [
{
"data" : 1,
"name" : "quick service"
}
],
"name" : "Time on hold"
},
{
"value" : [
{
"data" : 1,
"name" : "some words but strong accent"
},
{
"data" : 1,
"name" : "EZ to understand"
}
],
"name" : "Language fluency"
},
{
"value" : [
{
"data" : 1,
"name" : "Yes"
}
],
"name" : "Human answered"
},
{
"value" : [
{
"data" : 2,
"name" : "Like a hot potato"
},
{
"data" : 1,
"name" : "1 or 2 times"
}
],
"name" : "Transfered alot"
},
{
"value" : [
{
"data" : 3,
"name" : "ok time"
},
{
"data" : 1,
"name" : "quick service"
},
{
"data" : 1,
"name" : "short time"
}
],
"name" : "Time on Hold"
},
{
"value" : [
{
"data" : 1,
"name" : "some word but strong accent"
},
{
"data" : 2,
"name" : "EZ to understand"
}
],
"name" : "Language Fluency"
},
{
"value" : [
{
"data" : 2,
"name" : "Yes"
}
],
"name" : "Human Answered"
}
],
"average" : 81
},
"cat2" : {
"detail" : [
{
"value" : [
{
"data" : 1,
"name" : "It was ok"
},
{
"data" : 1,
"name" : "Not EZ at all"
},
{
"data" : 7,
"name" : "there were hidden gimicks"
},
{
"data" : 2,
"name" : "It was OK"
},
{
"data" : 1,
"name" : "Found Quickly"
}
],
"name" : "Easy to find desired product"
},
{
"value" : [
{
"data" : 1,
"name" : "Easy to understand"
},
{
"data" : 1,
"name" : "Eventually understood"
}
],
"name" : "Clear information about the product"
},
{
"value" : [
{
"data" : 2,
"name" : "none"
},
{
"data" : 3,
"name" : "There was but won't complain"
},
{
"data" : 1,
"name" : "Very Bad"
}
],
"name" : "Annoying popups"
},
{
"value" : [
{
"data" : 4,
"name" : "Eventually Understood"
},
{
"data" : 1,
"name" : "EZ to understand"
}
],
"name" : "Clear data about the product"
}
],
"average" : 71
},
"cat3" : {
"detail" : [
{
"value" : [
{
"data" : 1,
"name" : "Very quick"
}
],
"name" : "Prompteness"
},
{
"value" : [
{
"data" : 3,
"name" : "We're cool"
},
{
"data" : 4,
"name" : "They didn't like me"
}
],
"name" : "Friendlyness"
},
{
"value" : [
{
"data" : 3,
"name" : "Very Confusing"
},
{
"data" : 2,
"name" : "Still a little confused"
},
{
"data" : 3,
"name" : "Enlightened"
}
],
"name" : "Knowledge"
},
{
"value" : [
{
"data" : 3,
"name" : "On hold too many times"
}
],
"name" : "Promptness"
}
],
"average" : 69
}
}
]
}