I'm building a dynamic search query for a Mongo database.
In short, and not directly related to the question... it looks like this:
var searchCriteria = {}; <-- start with empty object
return db.users.find(searchCriteria,
{ sort: { username: 1 }
});
The values for searchCriteria come from a search form, basically like this:
var filter = $(form).find('select[name=filter]').val();
var query = $(form).find('[name=query]').val();
searchCriteria[filter] = query <-- Using a dynamic key
Example output from the form:
console.log(searchCriteria);
>> { username: "jdoe" }
So here's my hangup. I need to "unstringify" the query within the searchCriteria, and turn it into this:
>> { username: /jdoe/ }
I've tried replace, among other things, but it keeps ending up as a string value. I need the /query/ in that format for the Mongo find query.
Any suggestions? Thank you :)
You can easily turn a string into a RegExp object by using new Regex(string).
Note that this is bound to have some security issues somewhere if you're passing in user input, but new RegExp shouldn't allow any arbitrary JS to run, but it could still crash your code by being an invalid Regex.
Source (MDN)
Related
Not sure how to implement such a search with params as values and different params count. Looks like I need Regex & match. But params are not hardcoded in my matching (possible URLs array) - they are dynamic, and param value can be 0, 100, 777 and etc.
For example, I have such an array of strings to match:
[
'urlA/someId1',
'urlA/someId1/someSubUrlA/someId2',
'urlB/someId1/someId2'
'urlB/someId1/someSubUrlB/someId2'
]
ps: I can edit this array, so for example surround params with {} etc.
and when I try to run a search for: http://example.com/urlA/100/someSubUrlA/200
it should return urlA/someId1/someSubUrlA/someId2
when I try to run a search for: http://example.com/urlA/150
it should return urlA/someId1
and from what I can see I can use Regex & .match with .find(). But I'm confused about how to write custom matcher with custom parameters & their count. Is it possible somehow in JS?
Basically you want that given a url to find the abstract representation of it. Right?
let data = [
'urlA/someId1',
'urlA/someId1/someSubUrlA/someId2',
'urlB/someId1/someId2',
'urlB/someId1/someSubUrlB/someId2'
];
function finder(url) {
let afterDomain = url.match(/http:\/\/[^\/]*\.[^\/]*\/(.*)/)[1];
let matcher = afterDomain.replace(/\d+/g, "[^\/]+");
return data.find(x => (new RegExp(matcher)).test(x))
}
finder("http://example.com/urlA/100/"); // "urlA/someId1"
finder("http://example.com/urlA/100/someSubUrlA/200"); // "urlA/someId1/someSubUrlA/someId2"
I have a JSON string something similar to:
string str=[
{"name": "Dukes",
"lastname":"Chavez",
"salary":"10000",
"clearingbankAccinfo":"Westpac"}]
The issue is we have to clear the bank info, and that can be any value.
What we know for sure is it would come at the end of the string.
I need a regex pattern to remove this clearingbankAccInfo so that it looks something similar to:
string str=[
{"name": "Dukes",
"lastname":"Chavez",
"salary":"10000"}]
Unfortunately I would have not accepted this as input itself but this information comes from a diff process and I have no control over what they pass.
I have tried:
String str=str.replace(',"clearingbankAccInfo":\g[a-zA-Z0-9_:]\g+', '' )
But it doesn't work correctly
If you're working with something like JSON regex is the wrong solution. Simply parse the stringified data, and loop over it with something like map to extract and return the correct data. Then you can just make a string again out of that data.
const str = '[{"name": "Dukes","lastname": "Chavez","salary": "10000","clearingbankAccinfo": "Westpac"},{"name": "Bob","lastname": "Smith","salary": "20000","clearingbankAccinfo":"Lloyds"}]';
// Here we're creating a new variable called `newData` to hold
// the transformed data. We parse the data string and iterate over it
// (because it's now an array) with `map` which is an array method.
// With each iteration we take the object, grab the clearingBankAccinfo
// and just return everything else.
const newData = JSON.parse(str).map(obj => {
const { clearingbankAccinfo, ...rest } = obj;
return rest;
});
console.log(newData);
console.log(JSON.stringify(newData));
Additional documentation
Rest parameters
Working with JSON
Destructuring assignment
str=str.replace(/,?"clearingbankAccinfo":"\w+"/g, '');
I want to update all the fields in a MongoDB document and I have a Javascript object that contains all these fields. I could easily type out each field to update but this seems like a lot of manual work and not reusable. I wanted to do something like below but this creates an object containing all the new field data within the document called newData.
I've tried JSON.stringify on the variable but the format isn't appropriate for update.
var newData = {
_id:ObjectId("53245234..."),
id: 88888,
firstData: "someData",
secondData: 787855,
thirdData: [ 45,17,12,234]
};
var collection = db.get('CollectionToUpdate');
//strip out dB id so as not to overwrite it, possibly not needed
if ("_id" in newData) {
delete newData["_id"];
}
//find the correct document based on program generated id and update
collection.update({id: newData.id}, {
newData
})
If you trust newData will not have any keys you don't intend (like update operators) this should work:
var collection = db.get('CollectionToUpdate');
collection.update({id: newData.id}, newData)
Note that this replaces the document. I assume that is what you meant by "update all the fields". update does not replace "_id".
Documentation for update
I have an application that i have built, these servers send data back and forth, the master server i have setup gives me the messages in this format.
{ 'register 9f624ed': '' }
I would like to be able to split this key into different sections.
I have used the .split method, this doesn't seem to work for this purpose, i get all sorts of errors.
I would like to be able to cut off { '
leave me register in a variable
and then leave me 9f624ed in a variable.
Thanks for any advice anyone can offer!
You can use Object.keys() to obtain the keys on the object and then use .split() on one of the keys. Here's working code in a snippet:
var data = { 'register 9f624ed': '' };
var keys = Object.keys(data);
var splits = keys[0].split(" ");
// show output in snippet window
document.write(JSON.stringify(splits));
I have a web form with two drop-down boxes, and I'm looking for a way to dynamically update the options of the second box based on selections from the first.
The first box represents a data type, and the second box is a list of databases associated with the selected type.
I have the basic code running smoothly here:
var TypeA_DbSuffixList = ['Test1', 'Test2', 'Test3'];
var TypeB_DbSuffixList = ['TestA', 'TestB', 'TestC'];
function fill_dbSuffixList(){
document.getElementById("dbSuffixList").options.length = 0;
var suffixMenu = document.getElementById("dbSuffixList");
var dataFormat = document.getElementById("dataFormatType");
var suffixList = dataFormat.value + "dbSuffixList";
if (suffixList == 'TypeA_dbSuffixList') {
for(index in TypeA_dbSuffixList) {
suffixMenu.options[suffixMenu.options.length] = new Option(TypeA_dbSuffixList[index], index);
}
}
if (suffixList == 'TypeB_dbSuffixList') {
for(index in TypeB_dbSuffixList) {
suffixMenu.options[suffixMenu.options.length] = new Option(TypeB_dbSuffixList[index], index);
}
}
}
That code (activated whenever a selection is made in the dataType box) clears the existing list of options and repopulates the list based on the selected value of the "dataFormatType" box.
The problem that I face is that the actual lists of database tables are not hard coded and are instead generated with the following calls to the server to avoid repetitive editing of the page every time a new database is added:
var TypeA_dbSuffixList = ${TypeA_dbSuffixList};
var TypeB_dbSuffixList = ${TypeB_dbSuffixList};
These calls return the following code:
var TypeA_dbSuffixList = [Test1, Test2, Test3];
var TypeB_dbSuffixList = [TestA, TestB, TestC];
With the above code, the initial function treats each entry in the type arrays as an undefined variable, and nothing is ever written to the drop-down list.
If I were to add
var Test1 = "Apple";
var Test2 = "Orange";
var Test3 = "Grape";
prior to the "for" loop for TypeA, then selecting TypeA from the dataType drop-down list returns "Apple", "Orange", and "Grape" as the available databases for TypeA.
Visually, I see what needs to be changed. The [Test1, Test2, Test3] returns need to be ['Test1', 'Test2', 'Test3']. I'm just unsure exactly how to go about changing it, and have exhausted every web search I can think of.
Is there a way to either change the format of the returned arrays, or use the existing format and pass variable names as drop-down selections instead of using variable values?
Any help is greatly appreciated. I will continue to search for an answer on my own as well and will post it here should I find one.
I think the cleanest solution would be to change the code on the server-side to generate a proper JavaScript array of Strings, with the values enclosed in single or double quotes.
If that's not possible for some reason, and you want a pure-JavaScript solution, then I suggest you wrap the entire JSP/ASP/PHP variable (not sure what framework you're using) in double quotes, strip the string of brackets and spaces using a regex, and then split it into a string array using the comma as a delimiter.
So in your JavaScript, this:
var TypeA_dbSuffixList = ${TypeA_dbSuffixList};
would become this:
var TypeA_dbSuffixList = "${TypeA_dbSuffixList}".replace(/[\[\]\s]/g,"").split(",");
I think the best way to convert data in a server side language into something to be used in JavaScript is to JSON encode your objects.
I'm not sure what language your using on the server, but in PHP you can do the following
var arr = <?php echo json_encode( array ('abc', 'def', 'ghi') ); ?> ;
And your output will be
var arr = ['abc', 'def', 'ghi'] ;
This will make sure that strings with embedded new lines, tabs, quotes are properly escaped.
JSP
You said you're using JSP but the code you have looks more like velocity or free marker inside JSP. In JSP you could use the following, provided you download Gson
var TypeA_dbSuffixList = <%= new Gson().toJson(TypeA_dbSuffixList) %>;