Shorter way for find() query - node.js

I want to find if cell with provided coordinates exists in DB.
Is there a shorter way to create this query?
var schema = new mongoose.Schema({
coors: {
x: String,
y: String
}
});
// coors = {x:'1', y:'2'};
schema.statics.is_cell_exists = function (coors, callback){
var Cell = this;
var coors_x = {};
var coors_y = {};
coors_x['coors'] = {x: coors.x};
coors_y['coors'] = {y: coors.y};
var query = { $and: [coors_x, coors_y] };
Cell.find( query ).exec(...);
};

It just seems you have some unnecessary variables, etc. You can simply use dot notation to get inside that "coors" object and search on it.
Cell.find({ $and : [{ 'coors.x' : coors.x }, { 'coors.y' : coors.y }] })

Related

Query returning {} when it should return data

Im having trouble with a mongdb query returning {} from my node.js code.
Here is how I am building my query string in node.js javascript:
var idString = '' + firstId; // firstId = 1
var otheridString = '' + secondId; // secondId = 2
var users = { userid: { $in : [idString, otheridString] }};
But when I run this through nodeJS/mongo it returns {}
If I run this directly in the DB it returns the two rows
db.Users.find({ userid: { $in : ["1", "2"] }})
I think this has something to do with the userid's being strings, as if i run this query directly in the DB it returns {} also
db.Users.find({ userid: { $in : [1, 2] }})
Any help appreciated!
Please try this
var idString = firstId.toString(); // firstId = 1
var otheridString = secondId.toString(); // secondId = 2
var users = { userid: { $in : [idString, otheridString] }};

Why duplicates are save even if I use compound index? Mongo(Mongoose)

I am trying to save click coordinates on database but if x and y are the same I don't want to save them. Even if I use compound index and do everything by book, it still saves everything. There is similar question on stackoverflow but it doesn't work for my code.
Model, Schema:
var mongoose = require('mongoose');
var uniqueValidator = require('mongoose-unique-validator');
require('mongoose-double')(mongoose);
var Schema = mongoose.Schema;
var integerValidator = require('mongoose-integer');
var SchemaTypes = mongoose.Schema.Types;
var clickPoint = new Schema({
clicks: [
{
x: {
type: SchemaTypes.Double
},
y: {
type: SchemaTypes.Double
},
value: {
type: Number,
integer: true
}
}
]
});
clickPoint.index({x: 1, y: 1}, {unique: true});
clickPoint.plugin(integerValidator);
clickPoint.plugin(uniqueValidator);
//export model...
module.exports = mongoose.model("ClickPoint", clickPoint);
Model Controller:
var ClickPoint = require('../Models/point');
exports.addPoint = function (click) {
ClickPoint.findOne(function (err, data) {
if(!err) {
if(data) {
data.clicks.push({
x: click.x,
y: click.y,
value: click.value
});
data.save();
}
else {
var entry = new ClickPoint({
x: click.x,
y: click.y,
value: click.value
});
entry.save();
}
}
})
};
Could it be that all the records are stored in an array and as far as I know, index allows to store duplicates in array? If that is the problem than how would I keep objects unique in an array.
You index x & y, while the fields are clicks.x & clicks.y. If you're trying to add unique values to an array, why not use addToSet?

How to search in sub doc

I have an angular-fullstack app generated from angular-fullstack yeoman generator and I have a Query Model as follows:
'use strict';
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
/**
* Discussion Question Schema
*/
var QuerySchema = new Schema({
date: {
type: Date,
default: Date
},
tags: [{
type: Schema.ObjectId,
ref: 'Tag'
}]
});
module.exports = mongoose.model('Query', QuerySchema);
var deepPopulate = require('mongoose-deep-populate')(mongoose);
and Tag has a field text. Now in my query controller I have to deep populate some other fields and paginate them so, I am trying something like this in the controller function:
exports.index = function(req, res) {
var escapeRegExpChars = function (text) {
return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
};
require('paginate-for-mongoose');
var limit,page;
if(req.query.limit != undefined) limit = req.query.limit;
else limit = 10;
if(req.query.page != undefined) page = req.query.page;
else page = 1;
var queryObj = {};
if(req.query.searchText != undefined && req.query.searchText != '')
queryObj['title']= new RegExp(escapeRegExpChars(req.query.searchText), 'i');
var options = {
perPage:limit,
delta:2,
page:page
};
if(req.query.fold !=undefined && req.query.fold != '') queryObj["tags.text"] = req.query.fold;
var query = Query.find(queryObj).populate('tags','text').deepPopulate('user class user.class');
query.paginate(options,function(err, resp){
if(err) { return handleError(res, err); }
if(req.query.fold) console.log(resp.results);
return res.status(200).json(resp.results);
});
};
How do I search queries with tags.text value exactly as the req.query.fold value?
MongoDB doesn't support joins so to search on a linked doc you have to do it in two steps:
// First look up the _id of the tag
Tags.findOne({text: req.query.fold}, function(err, tag) {
if (tag) {
// Add a match in the doc's tags array to the tag's _id
queryObj.tags = tag._id;
var query = Query.find(queryObj)...
...
}
});

sequelize dynamic query params

I'm sending query params as JSON format in req.query.p from my front-end MVC framework , the point is that this could be a dynamic key and value, for example:
req.query.p = {nombre : 'juan'}
or
req.query.p = {pais : 'chile'}
So I need the key, and the value to put them in the where statement, something like this
exports.select = function(req, res){
console.log('=> GET | Obtener peliculas'.bold.get);
db.Pelicula
.findAndCountAll({
limit : req.query.limit,
offset : req.query.offset,
where : req.query.p ? [req.query.p.KEY + " = ?", req.query.p.VAL] : null
})
.success(function(resp){
console.log(JSON.stringify(resp.rows, null, 4).bold.get);
res.json({peliculas : resp.rows, meta : { total : resp.count}});
});
}
The where parameter can be an object, so you can just pass where: req.query.p
Usually I put the entire object, so if it comes empty, it will work normally as if there is no conditional WHERE.
You don't need to add {} in the where, because the object that comes from req.query already has it.
const filter = req.query;
example= await ModelExample.findAndCountAll({
where:
filter
})
With ES6 and with usage of the dynamic properties I'll do it like this
const { Op } = require("sequelize");
const from = new Date()
// const to = new Date().setMinutes(40)
const to = null
let where = {
timestamp: {
[Op.or]: {}
}
}
if (from) {
where.timestamp[Op.or][Op.gte] = new Date(from)
}
if (to) {
where.timestamp[Op.or][Op.lte] = new Date(to)
}
console.log(where);
Model.find({ where })

How to use a variable as a field name in mongodb-native findOne()?

I have this data in mongodb:
{
"name": "Amey",
"country": "India",
"region": "Dhule,Maharashtra"
}
and I want to retrieve the data while passing a field name as a variable in query.
Following does not work:
var name = req.params.name;
var value = req.params.value;
collection.findOne({name: value}, function(err, item) {
res.send(item);
});
How can I query mongodb keeping both field name and its value dynamic?
You need to set the key of the query object dynamically:
var name = req.params.name;
var value = req.params.value;
var query = {};
query[name] = value;
collection.findOne(query, function (err, item) { ... });
When you do {name: value}, the key is the string 'name' and not the value of the variable name.
Just put the variable in []
var name=req.params.name;
var value = req.params.value;
collection.findOne({[name]:value}, function(err, item) {
res.send(item);
});
I'd like to clarify that if you're trying to make a query concerning a nested field only (not its value), like if you want to query the field "name" from this document:
{
loc: [0, 3],
unit: {
name : "playername"
}
}
this will work (as in my case - using update):
mdb.cords.updateOne(
{_id: ObjectID(someid)},
{$set: {[query]: newValue}},
function (err, result) {
...
}
}
Simply enclosing [query] in brackets tells mongodb that it's not literal, but rather a path.
use like this if the object is nested.
Direct Object:-
var name=req.params.name;
var value = req.params.value;
collection.findOne({[name]:value}, function(err, item) {
res.send(item);
});
An object is nested:-
var surname=req.params.surname;
var value = req.params.value;
var condition = `name.${surname}`
collection.findOne({[condition]:value}, function(err, item) {
res.send(item);
});

Resources