I want to make a mongoose query from KeystoneJS. Something like below:
var keystone = require('keystone'),
Post = keystone.list('Post');
Post.model.find()
.where('state', 'published')
.populate('author')
.sort('-publishedAt')
.limit(5)
.exec(function(err, posts) {
// do something with posts
});
I checked the KeystoneJS v5, list created like:
keystone.createList('Post', {
fields: {
title: { type: Text },
},
});
If I query like:
var Post = keystone.list('Post');
I got keystone.list is not a function,
anyway to make a KeystoneJS retrieve query results?
Related
I want to get back a response like this , //JSON res format: [{"_id": data._id, "title": data.title}] . But it returns the whole collection, I can't get back a selective item like only the title from the collection.
My code snippet
const bookSchema = new mongoose.Schema({
title: String,
comments: []
})
const Books = mongoose.model("Books", bookSchema);
module.exports = function (app) {
app.route('/api/books')
.get(function (req, res){
//response will be array of book objects
//json res format: [{"_id": bookid, "title": book_title, "commentcount": num_of_comments },...]
Books.find({}, (err, data) => {
res.json(data.title)
})
})
.post(function (req, res){
var title = req.body.title;
//response will contain new book object including atleast _id and title
const newBookTitle = new Books({
title
})
newBookTitle.save(function(err, booksData) {
if(err) return res.json(err)
res.json(booksData)
})
})
data.title returns null value?
Model.Find() returns a Mongoose Query object. You would also need to do a query.Exec() to execute the query.
See the documentation here
Querying:
Finding documents is easy with Mongoose, which supports the rich query syntax of MongoDB. Documents can be retrieved using each model find, findById,findOne, or where static methods.
Tank.find({ size: 'small' })
.where('createdDate').gt(oneYearAgo)
.exec(callback);
See the chapter on queries for more details on how to use the Query API.
I'm using express to make the API for my web app. Below is the Schema for my annual budgets collection.
var {mongoose} = require('../db/mongoose');
var budgets = new mongoose.Schema({
year: Number,
categories: [{
name: String,
amount: Number
}]
});
var Budgets = mongoose.model('Budgets', budgets);
module.exports = {
Budgets
};
I am trying to passing in an array of categories using postman in the following way:
{
"year":2018,
"categories": [{
"name":"Logistics",
"amount":1500
}, {
"name":"Finance",
"amount":23030
}]
}
This the post request for my this collection. The request times out and is not saved in the database. I cannot seem to figure out what is wrong with the request. Please help
app.post('/annualBudgets', (req, res) => {
var categories = req.body.categories;
var budgets = new Budgets({
year : req.body.year,
});
budgets.categories.push(categories);
budgets.save().then((docs) => {
res.send(docs);
console.log(docs)
}).catch((e) => res.status(404));
});
The problem is here
budgets.categories.push(categories);
it should be
budgets.categories = categories;
// Alternatively
// budgets.categories.push(...categories);
because categories is already an array.
Using: node/express/mongodb/mongoose
With the setup listed above, I have created my schema and model and can query as needed. What I'm wondering how to do though is, pass the express request.query object to Model.find() in mongoose to match and query the _id of a nested document. In this instance, the query may look something like:
http://domain.com/api/object._id=57902aeec07ffa2290f179fe
Where object is a nested object that exists elsewhere in the database. I can easily query other fields. _id is the only one giving an issue. It returns an empty array of matches.
Can this be done?
This is an example and not the ACTUAL schema but this gets the point across..
let Category = mongoose.Schema({
name: String
})
let Product = mongoose.Schema({
name: String,
description:String,
category:Category
})
// sample category..
{
_id:ObjectId("1234567890"),
name: 'Sample Category'
}
// sample product
{
_id:ObjectId("0987654321"),
name:'Sample Product',
description:'Sample Product Description',
category: {
_id:ObjectId("1234567890"),
name: 'Sample Category'
}
}
So, what I'm looking for is... if I have the following in express..
app.get('/products',function(req,res,next){
let query = req.query
ProductModel.find(query).exec(function(err,docs){
res.json(docs)
})
})
This would allow me to specify anything I want in the query parameters as a query. So I could..
http://domain.com/api/products?name=String
http://domain.com/api/products?description=String
http://domain.com/api/products?category.name=String
I can query by category.name like this, but I can't do:
http://domain.com/api/products?category._id=1234567890
This returns an empty array
Change your query to http://domain.com/api/object/57902aeec07ffa2290f179fe and try
app.get('/api/object/:_id', function(req, res) {
// req._id is Mongo Document Id
// change MyModel to your model name
MyModel.findOne( {'_id' : req._id }, function(err, doc){
// do smth with this document
console.log(doc);
});
});
or try this one
http://domain.com/api/object?id=57902aeec07ffa2290f179fe
app.get('/api/object', function(req, res) {
var id = req.param('id');
MyModel.findOne( {'_id' : id }, function(err, doc){
console.log(doc);
});
})
First of all increase your skills in getting URL and POST Parameters by this article.
Read official Express 4.x API Documentation
Never mind I feel ridiculous. It works just as I posted above.. after I fixed an error in my schema.
I tried to use mongoosastic search but it doesnt work
Job.js (Mongoose schema)
var mongoose = require('mongoose');
var mongoosastic = require('mongoosastic');
var Schema = mongoose.Schema;
var JobSchema = Schema({
title: { type: String, es_indexed:true },
category: { type: Schema.Types.ObjectId, ref: 'Category', es_indexed:true},
salary: { type: String, es_indexed:true },
});
JobSchema.plugin(timestamps);
JobSchema.plugin(mongoosastic, {
hosts: [
'localhost:9200'
]});
module.exports = mongoose.model('Job', JobSchema);
Routes.js
var express = require('express');
var app = express();
var Job = require('../models/job');
Job.createMapping(function(err, mapping) {
if (err) {
console.log('error creating mapping (you can safely ignore this)');
console.log(err);
} else {
console.log('mapping created!');
console.log(mapping);
}
});
app.post('/api/search/', function(req, res, next) {
Job.search({query_string: {query: req.body.test}}, function(err, results) {
if (err) return next(err);
res.send(results);
});
});
This is the data sets that already been saved in mongodb
{
"id": 12313,
"title": "Engineer"
},
{
"id": 13123,
"title": "Doctor"
},
{
"id": 121243134,
"title": "Software Engineer"
}
When I tried to run the search and search like "Engineer" and I keep getting this result.
Updated for Curl
curl -XGET localhost:9200/_mapping
curl -XGET localhost:9200/_search
Since title is an analyzed String, its value is indexed using the standard analyzer, i.e. in lowercased form, so "Engineer" will be indexed and "engineer"
Try searching for "engineer" in lowercase instead.
UPDATE
Based on our discussion, it seems that the problem is simply that your Elasticsearch is empty. Since you have existing data in MongoDB, you need to make sure to call the synchronize() method on your model in order to index all your MongoDB collection inside Elasticsearch.
I am trying to update a document in MongoDB by finding it by the ObjectId. The work flow is as follows (this is for a blog).
Create a new post in MongoDB by passing a title and body. The ObjectId is automatically created.
Go to edit the post. It uses the ObjectId from the URL to grab it from the database and display it in the same new post form, just with the preexisting values.
When the submit button is clicked I want to find the document by the ObjectId and update the values in the database with those in the post form.
Step 1 & 2 work fine, but step 3 doesn't seem to be working. It redirects to the page I need it to. But the database has not been updated. It's the same value as it was before.
Here's the relevant code for the update post portion:
app.js
app.post "/office/post/:id/update", ensureAuthenticated, routes.updatePost
routes/index.js
mongoose = require 'mongoose'
ObjectId = mongoose.Types.ObjectId
Post = require '../models/Post'
...
updatePost: function(req, res) {
var o_id, the_id;
the_id = req.params.id;
console.log(the_id); // 510e05114e2fd6ce61000001
o_id = ObjectId.fromString(the_id);
console.log(o_id); // 510e05114e2fd6ce61000001
return Post.update({
"_id": ObjectId.fromString(the_id)
}, {
"title": "CHANGE"
}, res.redirect("/office/edit/posts"));
}
I'm using Express and Mongoose.
This is also the post model if that helps:
(function() {
var Post, Schema, mongoose;
mongoose = require('mongoose');
Schema = mongoose.Schema;
Post = new Schema({
title: String,
subhead: String,
body: String,
publish_date: {
type: Date,
"default": Date.now
},
mod_date: {
type: Date,
"default": Date.now
}
});
module.exports = mongoose.model('Post', Post);
}).call(this);
And here's the code for the edit blog post view:
app.js
app.get("/office/post/:id/edit", ensureAuthenticated, routes.editPost);
routes/index.js
editPost: function(req, res) {
return Post.findById(req.params.id, function(err, post) {
return res.render('edit-post', {
post: post,
title: post.title
});
});
}
The problem is how you call update
return Post.update({
"_id": ObjectId.fromString(the_id)
}, {
"title": "CHANGE"
}, res.redirect("/office/edit/posts"));
The last argument will actually redirect the page, whereas update expects a function to be called when the update is complete
You should pass in
return Post.update({
"_id": ObjectId.fromString(the_id)
}, {
"title": "CHANGE"
}, function(err, model) {
if (err) // handleerr
res.redirect("/office/edit/posts"));
});
That way, we only redirect once the model is successfully updated