mongoose - field contained in string - node.js

I need to make the following query, I have a model in the db that holds a string. for example lets say that's the data:
[{ a : 'test/t' },
{ a : 'test/b' }]
Now I have the following string
var search = 'http://ttt.com/test/t'
I want to make a query which will find all the documents that 'a' property is contained inside the search variable, case insensetive.
All the exmaples I've seen talk about the opposite equation.

You can use the following query for the operation which uses the short for $where. Since this runs in Javascript, expect it to run slowly.
db.coll.find(function () {
var re = new RegExp(this.a.replace("/", "\/"))
return 'http://ttt.com/test/t'.match(re)
});

Related

Find query in mongodb using cases

I have a collection of product in which I have document like this
"_id" : ObjectId("5acb1dad698eaa7a254c9017"),
"txtProductCode" : "1233A",
"txtModelCode" : "00M",
"txtPartNo" : "00P",
"txtSerialNo" : "00S",
"txtProductName" : "Watch",
"traderId" : ObjectId("5ac5fb29b0f9b3444e6c1ef2")
I want to search a product based on its name and traderId for which I used
db.getCollection('product').find( {$and:[{'txtProductName':"Watch"},{"traderId" : ObjectId("5ac5fb29b0f9b3444e6c1ef2")}]})
its working fine but now if a user have input model no then it shoud use model number also to search for a product if the user have not input the model no then it should without model number
So My question is do I have to use cases like this
if(req.body.modelNo)
db.getCollection('product').find( {$and:[{'txtProductName':"Watch"},{"traderId" : ObjectId("5ac5fb29b0f9b3444e6c1ef2")},{'txtModelCode':"00M"}]})
else
db.getCollection('product').find( {$and:[{'txtProductName':"Watch"},{"traderId" : ObjectId("5ac5fb29b0f9b3444e6c1ef2")}]})
or is there a way to do this without making cases I have to do this for multiple condtions so I am trying not to use cases
Create the query object first then add the extra key with a conditional check. No need to explicitly use the $and operator when specifying a comma separated list of expressions as it's implicitly provided:
let query = {
'txtProductName': 'Watch',
'traderId': ObjectId('5ac5fb29b0f9b3444e6c1ef2')
};
if (req.body.modelNo) query['txtModelCode'] = req.body.modelNo;
db.getCollection('product').find(query);
If using the $and operator, you can push the additional query into an array then use the list for the $and operator:
let andOperator = [
{ 'txtProductName': 'Watch' },
{ 'traderId': ObjectId('5ac5fb29b0f9b3444e6c1ef2') }
];
if (req.body.modelNo) andOperator.push({ 'txtModelCode': req.body.modelNo });
// if (req.body.modelNo) andOperator = [...andOperator, { 'txtModelCode': req.body.modelNo }];
db.getCollection('product').find({ '$and': andOperator });
Well, I would have done this in this way
First, you should send a json of specific from to backend. for example
[{'txtModelCode':"00M"},{'txtPartNo':"AC"},{'Yts':"xyz"}]
OR
[{'txtModelCode':"00M"},{'txtPartNo':"AC"}]
OR
[{'txtModelCode':"00M"}]
This is the payload that you should expect in req.body. And finally you can use it in your find() criteria. Something like
db.getCollection('product').find( {$and:[{'txtProductName':"Watch"},
{"traderId" : ObjectId("5ac5fb29b0f9b3444e6c1ef2")}, ...req.body]})
... is called spread operator. Spread syntax allows an iterable such as an array expression or string to be expanded. Read more about it here
This will make it totally dynamic. Any scaling in collection can directly be used in find criteria. you never have to add extra line of code

single quote added to string when building a mongo string

I am trying to build query string to find documents in mongodb.
I have a variable assigned for the value in the key:value pair.
My code looks like below
var query = {"_id":orgId[0]};
var name = "_id";
console.log(query);
db.collection('orgs')
.findOne({query}, function (err,result) {
});
The value of query looks like the below
{ _id: '"567a701be4b017"' }
Its basically adding a single quote around the string value and therefor the result from the query is null. How can i get past this ?
Thanks
Sam

Update by Id not finding document

I am attempting to perform a relatively simple update using Mongoose:
var location = locationService.getLocation(typedLat, typedLong, travelRadius);
DocumentModel.update({_id : passedInId }, { location : location }, function(err, resp){
next(err, resp);
});
In this case passedInId is the string:
"561ee6bbe4b0f25b4aead5c8"
And in the object (test data I created) the id is:
"_id": ObjectId("561ee6bbe4b0f25b4aead5c8")
When I run the above however, matched documents is 0. I assume this is because passedInId is being treated like a string, however when I type it to an ObjectId:
var queryId = ObjectId(passedInId)
The result is the same, the document doesn't match. What am I missing? This seems like it should be obvious....
Mongoose will correctly interpret a string as an ObjectId. One of the following must be the case:
That record is not in the collection. Run a query in the mongo shell to check.
Mongoose I'd looking in collection other than the one containing your test data. Remember, by default, mongo will lowercase the name under which you register your model and will add an a "s" to it.
Lastly, and your answer speaks to this, maybe your model it's just not being updated with any new information.
This behavior was because I had not yet updated the model in mongoose to include the location element. There is no error, it just doesn't match or do anything.

find function in mongodb and literal objects

I use Mongoose on nodeJS and I have the following schema in MongoDB:
var users = new Schema({
local: {
user_uuid: String
,user_name: String
,password: String
,email: String
,connectionKey: String
}
});
And I'm exporting the schema in the following way:
module.exports.users = mongoose.model('users',users);
and this is my find statment:
var AllSchemas = require('../schemas/schemas');
...
AllSchemas.users.find({ user_uuid: doctorId},function(err,obj){
...
}
but I get that the user is not found.
If I take all the parameters out of the literal object "local" it will work
I want to know how can I find things inside a literal object.
You need to use dot notation to reach inside of embedded documents in your query:
AllSchemas.users.find({ 'local.user_uuid': doctorId }, function(err,obj) {
...
}
While referring to a sub object in the schema, you should use the dot notation inside quotes.
Please refer the following link to get the more information about the dot notation
http://docs.mongodb.org/manual/core/document/#document-dot-notation
In your case, you should use:
AllSchemas.users.find({ 'local.user_uuid': doctorId},function(err,obj){
...
}
This query will return you all the documents having user_uuid equal to doctorId.

How do I get this nested schema working in Mongoose?

So I'm trying to figure out how to how to save multiple commands in a command list but everything I've tried hasn't worked. This is how I have it set up so far but when it saves, it saves in the format of
"command_list" : [ { "action" : "goto,goto", "target" : "http://www.google.com,http://www.cnn.com" } ]
when I really want something like
"command_list" : [ "command" : { "action" : "goto", "target" : "http://www.google.com" },
"command" : { "action" : "goto", "target" : "http://www.cnn.com" } ]
where there are multiple commands. So far my app.js is storing the data like this
var configSample = new Configurations({
command_list_size: request.body.command_list_size,
command_list: [ {action: request.body.action, target: request.body.target}]
});
and the model looks like this
var mongoose = require("mongoose");
var command = mongoose.Schema({
action: String,
target: String
});
var configSchema = mongoose.Schema({
command_list_size: Number,
command_list: [command]
});
module.exports = mongoose.model('Configurations', configSchema);
So how do I get that nesting action going? Thanks!
It looks like you're not packing the data right when you send it to the server. If you use the following:
command_list: [ {action: request.body.action, target: request.body.target}]
it's going to grab all of the actions and lump them together and do the same with the targets. You'd be better off sending an array to your server with the documents already nested in them.
The other option would be to parse the data to pull out the elements once you receive it on your server, but I think it'd be easier to just package it right in the first place.
ADDITION:
If you wanted to split what you have, you could use the String.split() method and rebuild the object:
// not certain the chaining will work like this, but you get the idea. It works
// on the string values you'll receive
var actions = response.body.action.split(',');
var targets = response.body.target.split(',');
// the Underscore library provides some good tools to manipulate what we have
// combined the actions and targets arrays
var combinedData = _.zip(actions, targets);
// go through the combinedData array and create an object with the correct keys
var commandList = _.map(combinedData, function(value) {
return _.object(["action", "target"], value)
});
There may be a better way to create the new object, but this does the trick.
EDIT:
I created a question about trying to refactor the above code here.

Resources