This question already has an answer here:
How to add data to array in Mongoose Schema
(1 answer)
Closed 6 years ago.
I have just started using node with express framework and mongo as a database.
I created the schema like this :
var JsonSchema = new Schema({
type: String,
properties: {
OBJECTID: Number,
AREA: Number,
PERIMETER: Number,
ESYE_CODE: Number,
Descriptio: String
},
geometry: {
type: String,
coordinates: [Number, Number]
}
});
and then I query :
router.get('/mapjson/:OBJECTID', function(req, res) {
if(req.params.OBJECTID) {
Json.findOne({OBJECTID: req.params.OBJECTID }, {}, function(err, docs){
res.json(docs);
} else {
console.log("THERE WAS AN ERROR HERE!!!");
}
});
But the results I get are missing the geometry field.
Sample of results I get :
{
"_id":"57e43ec60534d33ccc13099b",
"type":"Feature",
"properties":{
"OBJECTID":212428,
"AREA":131.001991421,
"PERIMETER":49.9141344212,
"ESYE_CODE":147,
"Descriptio":"Ελληνικά"
}
}
and what I get when I query the collection from mongo shell :
db.points.findOne({'properties.OBJECTID': 212428})
{
"_id" : ObjectId("57e43ec60534d33ccc13099b"),
"type" : "Feature",
"properties" : {
"OBJECTID" : 212428,
"AREA" : 131.001991421,
"PERIMETER" : 49.9141344212,
"ESYE_CODE" : 147,
"Descriptio" : "Ελληνικά"
},
"geometry" : {
"type" : "Point",
"coordinates" : [
23.812561006040106,
38.093951650544334
]
}
}
In coordinates you can set type as Array:
geometry: {
type: String,
coordinates: Array
}
Related
My Model which has coure_name, c_material as array, c_task as array and I am trying to fetch the results based on the below query:
const taks_schema = mongoose.Schema({
course_name : {
type : String,
required : true,
unique : [true, "Someone register using this email"],
trim : true
},
c_material : [
{
m_name : {
type : String
},
m_link : {
type : String
},
m_file : {
type : String
},
m_date : {
type : String
}
}
],
c_task : [
{
t_name : {
type : String
},
t_details : {
type : String
},
t_start_date : {
type : Date
},
t_end_date : {
type : Date
},
t_q_file : {
type : String
},
t_s_file : [
{
t_s_email: {
type : String
},
t_s_file_inner : {
type : Array
},
t_s_file_Date : {
type : Date
}
}
]
}
]
});
I apply this query which searches through the database, but get 0 modified in the result object.
let submit_files = await stu_task.updateOne({$and: [{course_name : "Web Development with Node js"}, {c_task : {_id : req.body.task_id}}]}, {$set : {c_task : {t_s_file : {t_s_email : check_cookie.email, t_s_file_inner : files_names, t_s_file_Date : Date.now()}}}});
Is there any problem in the query that I have created?
You don't have "c_task._id" defined in the schema , but you have it in the updateOne search criteria ...
You also need arrayFilters to update nested arrays check the documentation and also you need a id to search in t_s_file array in following query is used t_s_email field because I don't know the real data, so I searching in t_s_file based on t_s_email can using _id if exist
await stu_task.updateOne(
{
$and: [
{ course_name: "Web Development with Node js" },
{ "c_task._id": req.body.task_id },
],
},
{
$set: {
"c_task.$[].t_s_file.$[i].t_s_email": {
t_s_email: check_cookie.email,
t_s_file_inner: files_names,
t_s_file_Date: Date.now(),
},
},
},
{ arrayFilters: [{ "i.t_s_email": "email#gmail.com" }] }
);
This question already has answers here:
How to push an array of objects into an array in mongoose with one call?
(4 answers)
Closed 3 years ago.
I'm using Angular 7 with node.js, express and mongoose
I have a problem when adding objects to my mongodb via mongoose, it saves only "_id": ObjectId('randomID') instead of the values i want.
I'm trying to add values to an existing document in my collection with nested arrays.
To be more precise: there are customers with a customer number, customer name and domains.
Domains shall be an array with a domain.
A domain has a name value and two more arrays (called "in" & "out")
both arrays contain a graph array with nodes and links.
nodes have 3 values (id, label, description) and links have also 3 values (source, target, label)
First Problem I have, is that I cant add new domain to my domains array
I don't understand what am I am doing wrong??
Or what is best practice to insert and/or update nested arrays inside nested arrays?
edit: I try to understand, why am I saving only the ObjectId() with no values, linked question doesn't work for me.
here is an Example of what i want in my db:
{
"_id" : ObjectId("5c76a093aac6fa3f140a5672"),
"KdNr" : "10004",
"Kundenname" : "Customer GmbH",
"__v" : 0,
"domains" : [ {
"domain" : "testB.de",
"in" : [ {
"content" : "New Graph B",
"graph" : { ... } } ],
"out" : [ {
"content" : "Another new Graph B",
"graph" : { ... } } ]
}, [ {
"domain" : "testA.de",
"in" : [ {
"content" : "New Graph A",
"graph" : { ... } } ],
"out" : [ {
"content" : "Another new Graph A",
"graph" : { ... } } ]
} ]
}
here is an Example of what i get (not what I want):
{
"_id" : ObjectId("5c76a093aac6fa3f140a5672"),
"KdNr" : "10004",
"Kundenname" : "Customer GmbH",
"__v" : 0,
"domains" : [ {
{ "_id" : ObjectId("5c7f86ad42d63141fc921d04") },
{ "_id" : ObjectId("5c655c828be0b2b295aa126f") }
] }
here is my Schema:
const mongoose = require('mongoose');
const graphSchema = mongoose.Schema({
graph: {
nodes: [{
id: { type: String, required: true, unique: true },
label: { type: String, required: true },
description: { type: String }
}],
links: [{
source: { type: String, required: true },
target: { type: String, required: true },
label: { type: String }
}]
}
});
const domainSchema = mongoose.Schema({
domain: {
name: { type: String, unique: true, required: true },
in: {
content: { type: String },
graphSchema
},
out: {
content: { type: String },
graphSchema
}
}
});
const diagramSchema = mongoose.Schema({
KdNr: { type: String, required: true, index: true, unique: true },
Kundenname: { type: String, required: true },
domains: [{
domainSchema
}]
});
module.exports = mongoose.model('Diagram', diagramSchema);
here is my domains-routes.js:
// core Modules
const express = require('express');
// own modules
const Diagram = require('../models/diagrams');
const router = express.Router();
// add Domain to Diagram
router.put('/:KdNr', (req, res, next) => {
console.log(req.body.domain);
const data = {
domains : [{
domain: req.body.domain,
in: [{
content : "New Graph",
graph : {}
}],
out: [{
content : "New Graph",
graph : {}
}]
}]
}
Diagram.updateOne(
{ KdNr: req.params.KdNr },
{ $push: data }
).then(result => {
if(result) {
console.log('Diagram found in database:');
console.log(result);
res.status(200).json({ message: 'Diagram saved' });
} else {
res.status(404).json({ message: 'Diagram for customer: '
+ req.params.KdNr + 'not found!'})
}
})
})
module.exports = router;
Try this in
Diagram.updateOne
{ $push:{"domains": data }}
Given the following document in my DB:
{
"_id" : ObjectId("5c03b36d13032cc192d33f84"),
"type" : "Feature",
"properties" : {
"name" : "point 1",
"amenity" : "test",
"popupContent" : "test"
},
"geometry" : {
"type" : "Point",
"coordinates" : [
[ -3.68814468383789,
40.5248912033234]
]
}
}
And given the following mongoose query:
function findVertex(req,res){
Vertex2.find({"_id":"5c03b36d13032cc192d33f84"}, function(err,obj) {
if(err){
res.status(500).send(error);
}else{
var geoJson=obj[0];
console.log(geoJson)
res.status(200).send(geoJson);
}
})
}
What I receive is:
{ properties: { name: 'point 1', amenity: 'test', popupContent: 'test' },
_id: 5c03b36d13032cc192d33f84,
type: 'Feature' }
Why geometry is not in the response? If I do the same query in robomongo I have the object with the coordinates.
Base of mongoDb GeoJSON object documnet your point geometry structure is incorrect, coordinates must be an array with 2 element, not an array that contain another array
At the end I have fixed it changing the model schema.
Initially I had this:
_id:String,
type:String,
properties:{
name:String,
amenity:String,
popupContent:String
},
geometry:{
type:String,
coordinates:[]
}
Now I have this:
type:String,
properties:{
name:String,
amenity:String,
popupContent:String
},
geometry:{
type: {type: String, default: 'MultiPoint'},
coordinates: {type: []}
}
And I have the desired object in return:
{"properties":{"name":"Coors Field","amenity":"Baseball Stadium","popupContent":"This is where the Rockies play!"},"geometry":{"type":"MultiPoint","coordinates":[[-3.68814468383789,40.5248912033234],[-3.70814468383789,40.5248912033234],[-3.68230819702148,40.5074040815359]]},"_id":"5c03a3da82822133f0406667","type":"Feature","__v":0}
I'm curious what the best way to structure my mongoose Schema is. I'm making a movie site with the User schema set like this:
let UserSchema = new mongoose.Schema({
username: {
type: String,
index: true
},
password: {
type: String
},
email: {
type: String
},
name: {
type: String
},
watchlist: [mongoose.Schema.Types.Mixed],
seen: {
like : {
type: [mongoose.Schema.Types.Mixed]
},
dislike: {
type: [mongoose.Schema.Types.Mixed]
}
},
});
When a user clicks either a thumbs up or thumbs down icon, an object of
{movieID: movieID, title: movieTitle, poster: moviePoster}
will be sent to the like or dislike array in the seen property. I'm going to use this info in my EJS template to determine if a movie has already been seen and if seen and liked then gray out the dislike button and if seen and disliked gray out the like button. I also want to be able to remove the item from seen if the use clicks a 'clear' button. In order to do that it seems like I'm going to have to loop over both arrays in order to determine if the movie is included in one and then remove it. Seems like there has to be a better way to do it. I was thinking of structuring the 'seen' object using the movieID as a key, like this:
seen: {
'123': {
movieID: '123',
title: 'movieA',
poster: 'movieA-poster.jpg',
like: true
},
'456' : {
movieID: '456',
title: 'movieB',
poster: 'movieB-poster.jpg',
like: false
}
}
But when I try to send the data to seen using .findOne and this function:
const movieObj = {
id: req.body.movieID,
title: req.body.movieTitle,
poster_path: req.body.poster_path,
};
User.findOne({_id: req.user._id}, function(err, user) {
if (err) {
console.log(err);
} else {
user.seen[req.body.movieID] = movieObj;
user.save(function(){});
}
}
I still just get an empty object returned to me. I changed the schema seen object to:
seen: { type: mongoose.Schema.Types.Mixed, default: {} }
and have set {minimize: false}, because I read that mongoose by default doesn't allow empty objects. Appreciate any guidance on what I'm doing wrong or if you have a better way to efficiently structure the schema to allow seen movies to easily be added or removed from the db.
I think mongoose populate will help you here.
Just read about it, you will get a good idea about it.
Here is a good link with an example:
https://hashnode.com/post/how-do-i-successfully-populate-a-mongoose-schema-cj339r6kt004g5mk83ycujilq
Please look this Models and queries that can help you do build your schemas.
1.User Schema
let UserSchema = new mongoose.Schema({
username: {
type: String,
index: true
},
password: {
type: String
},
email: {
type: String
},
name: {
type: String
},
watchlist: [mongoose.Schema.Types.Mixed],
like : [mongoose.Schema.Types.ObjectId], //remove
deslike : [mongoose.Schema.Types.ObjectId], //remove
seen : [{
movieId : { type: : mongoose.Schema.Types.ObjectId, ref: 'Movie' },
isStatus : {type : string} //Enum [like,dislike,'seen']
}]
})
2.Movie Schema
let movieSchema = new mongoose.Schema({
tile: {
type: String
},
description: { type: String }
})
3.Data store in Both Table
/user/
{
"_id" : ObjectId("5b5acaf0589ff6bfb5dd091f"),
"seen" : [
{
"movieId" : ObjectId("5b9e2544953b5f69683059d4"),
"isStatud" : "like"
},
{
"movieId" : ObjectId("5b9e2544953b5f69683059d6"),
"isStatud" : "dislike"
},
{
"movieId" : ObjectId("5b9e256d953b5f69683059ee"),
"isStatud" : "seen"
}
]
"like" : [
ObjectId("5b9e2544953b5f69683059d4"),
ObjectId("5b9e256d953b5f69683059ee")
],
"deslike" : [
ObjectId("5b9e2544953b5f69683059d6")
]
}
/movie/
{
"_id" : ObjectId("5b9e2544953b5f69683059d4"),
"title" : "movie1",
"description" : "desc1"
}
{
"_id" : ObjectId("5b9e2544953b5f69683059d6"),
"title" : "movie2",
"description" : "desc2"
}
{
"_id" : ObjectId("5b9e256d953b5f69683059ee"),
"title" : "movie3",
"description" : "desc3"
}
Query to get users by movie
/This is working fine and tested/.
db.getCollection('user').aggregate([{
$match : { _id : ObjectId("5b5acaf0589ff6bfb5dd091f") }
},
{$lookup : {
from : 'movie',
localField : 'like',
foreignField : '_id',
as : "likes"
}},
{$lookup : {
from : 'movie',
localField : 'deslike',
foreignField : '_id',
as : "deslikes"
}}
])
/Query with group/
db.getCollection('user').aggregate([{
$match : { _id : ObjectId("5b5acaf0589ff6bfb5dd091f") }
},
{$unwind : '$seen'},
{$lookup : {
from : 'movie',
localField : 'seen.movieId',
foreignField : '_id',
as : "seen.movieData"
}},
{$unwind : '$seen.movieData'},
{ $group: { "_id": "$_id",
"name" : { "$first": "$name" }, //use same all other field of user
"seen" : {"$push" : "$seen"}
} ,
}
])
Please check and let me know any help.
I don't understand why my query doesn't work with MongoDb $geoNear ?
I checked this issue without success : mongodb geoNear command with filter
My environment :
NodeJs : V6.6.0
Mongoose : 4.8.6
this works
db.collection.geoNear(
coords,
{
query : { status: "1" } }, // I have the good filtered results
...
I already tested
...
query : { _id: { $in: itemIds } }, //no error and empty result
query : { "_id": "5639ce8c01f7d527089d2a74" }, //no error and empty result
query : { "_id" : 'ObjectId("5649e9f35f0b360300cad022")' }, //no error and empty result
query : { "_id" : ObjectId("5649e9f35f0b360300cad022") }, //error ObjectId not defined
...
I want this
db.collection.geoNear(
coords,
{
query : { _id: { $nin: poiIds } }, // no error but I have not the good results because I obtain all results geolocalized
...
Thank you ;-)
For this issue:
query : { "_id" : ObjectId("5649e9f35f0b360300cad022") }, //error ObjectId not defined
Try:
const ObjectID = require('mongodb').ObjectID
In my case, I did it like this:
Add index to coords in your model, then request with query.
modelSchema.index({ coords: '2dsphere' });
query = {
_id: {
$nin: poiIds
},
coords: {
$near: {
$geometry: { type: "Point", coordinates: position }
}
}
}
where position is an array [Lat, Lon].
Hope this helps. ;)