How can I write a compound WHERE condition using documentdb? - javascript

I have a document that looks like this:
{
"email": "joan.smith#somedomain.com",
"name": {
"first": "Joan",
"last": "Smith"
}
}
How can I write a SQL query that uses a compound comparison against the entire last name?
This is effectively what I'd like to do in the WHERE:
SELECT *
FROM c
WHERE c.name.first + " " + c.name.last = "Joan Smith"
The "plural" version
SELECT *
FROM c
WHERE c.name.first + " " + c.name.last
IN ("Joan Smith", "Juan Suarez")
Both of these queries will run in the Azure Portal without error, but they return empty results. I have tried wrapping the concatenation in parentheses but this has no effect.

According to the Cosmos DB SQL APIs , if you want to implement concatenation in Cosmos DB SQL, you need to use || instead of +.
So, please modify your sql as below:
SELECT c.id,c.name
FROM c
WHERE c.name.first || " " || c.name.last = "Joan Smith"
Then you could get the results you want.
Hope it helps you.

Related

Sequelize query string prefix / starts with

I'm building an autofill function that takes a string input and returns a list of string suggestions.
Sequelize's iLike:query returns every string in which the queried string appears. I would like to favour strings for which the query is a prefix. For example when query='sh' then the results should return strings that start with sh instead of having sh anywhere within the string.
This is relatively simple to do after receiving the data from the DB, however I was wondering if there is a way to accomplish this via sequelize while querying the DB? If so how?
The DB size will be between 10,000 and 100,000 strings of no more than a handful of words (company names to be exact).
Optional question: DB's usually have superior performance to generically written code, in this circumstance should there even be a noticeable difference? Or should I just collect all the data from the DB and apply some other filters on it after via vanilla JS.
let suggestions = yield db.Company.findAll({
limit: 7,
where: {
company_name: {
$iLike: '%'+this.data.query
}
}
})
Seems like this is super easy! The '%' acts like a * from regex. So query + '%' returns any results where query is the prefix.
let suggestions = yield db.Company.findAll({
limit: 5,
where: { $or: [
{ stock_ticker: { $ilike: query + '%' } },
{ company_name: { $ilike: query + '%' } }
]},
order: '"volume" DESC'
})

Passing sort order as a parameter

Referring to the sample SQL statement below. I'm able to pass parameter values to the placeholder '?' in the statement. However I'm wondering whether it is possible to pass in the sort order in the same way?
So instead of this:
//Create SQL query
var getAccountsTransactionsStatement = WL.Server.createSQLStatement(
"SELECT transactionId, fromAccount, toAccount, transactionDate, transactionAmount, transactionType " +
"FROM accounttransactions " +
"WHERE accounttransactions.fromAccount = ? OR accounttransactions.toAccount = ? " +
"ORDER BY transactionDate DESC " +
"LIMIT 20;"
);
Can I have this:
//Create SQL query
var getAccountsTransactionsStatement = WL.Server.createSQLStatement(
"SELECT transactionId, fromAccount, toAccount, transactionDate, transactionAmount, transactionType " +
"FROM accounttransactions " +
"WHERE accounttransactions.fromAccount = ? OR accounttransactions.toAccount = ? " +
"ORDER BY ? DESC " +
"LIMIT 20;"
);
And to invoke it:
//Invoke prepared SQL query and return invocation result
function getAccountTransactions1(accountId){
return WL.Server.invokeSQLStatement({
preparedStatement : getAccountsTransactionsStatement,
parameters : [accountId, accountId, transactionDate]
});
}
Two things:
This query piece:
WHERE accounttransactions.fromAccount = ? OR accounttransactions.toAccount = ?
Could be replaced with this:
WHERE ? in (accounttransactions.fromAccount, accounttransactions.toAccount)
No you can't. Parameters are values - kind of static stuff - while column names are not. You could probably work around the issue somehow in limited way by using s.t. like this:
ORDER BY
CASE ?
WHEN 'transactionDate' THEN transactionDate
WHEN 'someotherdate' THEN someotherdate
ELSE DATE '2010-01-01'
END
Note however that's a messy construction. Also depending on the type of the database you're using you might want to cast all the columns into one data type i.e. string. so to_char(transactionDate,'yyyy-mm-dd hh24:mm:ss') might be in order but you need to ensure that the sorting is proper in your case (as number tend to mess stuff up like '2' > '13').

JS String concatenate encoding issue

I have two html datalists, and I get their input values to query a json file. I first search the keys of my json file which are college majors, their values are their courses. So once the object key equals the program, I return that element because I want to further query that element with the second input field which is a course number. This step is always successful at returning the correct program courses corresponding to the program input.
The second step is where things go bad. I want to now take that program element and look through all the names of the courses in that program. I concatenate the two input fields, program + " " + course. The program is a major like "CSE" or "I S" and the course is any 3 digit number like "143" or "310". Each object element in the program has a string name attribute like "CSE 143". This name attribute does not equal the program + " " + course even though they are both of type string and the same value WHEN I am looking at a program that has a space in it. For example, I want to find the course "I S 310". I successfully search for the program name that equals "I S". I iterate through the keys and find the correct element value using this operation Object.keys(jsondata[index]) == program. program is a variable containing the string "I S". As stated previously, this is successful, but if I iterate through the children of that objectkey value to find id, like programdata[index].children == program + " " + course, it doesnt work. If I instead hardcode the value, programdata[index].children == "I S 310", it works! This leads me to believe that the concatenation operation for these two variables changes the encoding of the string. According to console.log, the type of "I S 310" and program + " " + course are both Strings except they output a different encodeURIComponent().
Ill write what the output to the console is since im not reputable enough:
Step 1
function getProgramCourses(data, program) {
var programKeys = Object.keys(data);
for (var i = 0; i < programKeys.length; i++) {
if (Object.keys(data[i]) == program) {
return data[i][Object.keys(data[i])];
}
}
return objs
}
program = "CSE"
console.log(program)
console.log(encodeURIComponent(program));
Output:
CSE
CSE
program = "I S"
console.log(program)
console.log(encodeURIComponent(program));
Output:
I S
I%C2%A0S
Those unencoded hidden characters dont affect this first step of finding the courses offered by the "I S" program. Now when I want to find a specific course within the "I S" program like "I S 310":
Step 2
//data is object array of all courses in this program
function getCourse(data, program, course) {
pc = program + " " course;
for (var i = 0; i < data.length; i++) {
if (data[i].name == pc) {
return data[i];
}
}
}
"CSE" = program and "143" = course
pc = program + " " + course;
console.log(pc)
console.log(encodeURIComponent(pc));
Output:
CSE 142
CSE%20142
["I S" = program and "310" = course][2]
pc = program + " " + course;
console.log(pc)
console.log(encodeURIComponent(pc));
Output:
I S 310
I%C2%A0S%20310
This second step only works for programs that dont have spaces like "CSE" or "MATH". Doesnt work for "A A" or "I S". data[i].name is type String and so is pc.
Sorry about the lengthy post, I just wanted to be as descriptive as possible. Any help would be greatly appreciated.
Basically
Here is my problem:
console.log("A A 198")
console.log(encodeURIComponent("A A 198"))
console.log(program + " " + course)
console.log(encodeURIComponent(program + " " + course))
Output:
A A 198
A%20A%20198
A A 198
A%C2%A0A%20198
not equal
Your program variable contains a character which is like a space but isn't a space. Make sure it isn't an encoding issue, else you can fix this with this simple code.
encodeURIComponent(program.replace(/\u00a0/g, ' ') + ' ' + course)

WebSQL: Error processing SQL: number of '?'s in statement string does not match argument count

I want to create a dynamic function to INSERT data into the webSQL Database. I cannot use indexed DB because Zetakey does not support it.
tx.executeSql("INSERT INTO " + table + "(" + formatfields + ")
VALUES (" + formatqm + ")",
[formatvalues],
webdb.onSuccess,
webdb.onError);
Ich übergebe an den Query:
formatfields = "one, two"; (up to an undefined number)
formatqm = "?, ?";
formatvalues = "123, 456"; (dynamic user entries for x fields)
Can someone tell me what do I have to do with the formatvalues? When I write 123, 456 directly its working fine.
Thanks in advance!
Instead of dynamically create or change table column fields, use JSON serialization of the record. Basically store stringify user given object data on INSERT and parse on retrieval. If you need query over column, initialize those columns only. It will be just like IndexedDB does.
/*array.push */
formatvalues = new Array;
formatvalues.push("123");
and so on!

In Javascript, how do you access key value data from an object in a mixed array?

my name's Mike and my question is two-fold:
How can I access the objects in my array so that they properly appear in my question prompt, and
How can I access the properties of the randomely selected object in an if/else statement?
I'm trying to make a simple flashcard program to help me memorize different kinds of sound equipment. The list of equipment is large but I'm only including three different kinds to keep this example simple. I want each object to have two properties: answer and desc. This first part defines three objects, places them in an array, creates a variable for picking one of the array items randomely, and another variable for prompting the user for an answer:
var newFlash = function() {
var A827 = {
answer: "T",
desc: "Multitrack Tape Recorder"
};
var LA2A = {
answer: "O",
desc: "Classic Leveling Amplifier"
};
var SonyC800G = {
answer: "M",
desc: "Tube Condenser Microphone"
};
var list = [A827, LA2A, SonyC800G];
var rand = Math.floor(Math.random() * list.length);
var question = prompt("What kind of equipment is " + list[rand] + "?");
};
Now, if I make my three items in my array all strings, they show up no problem in the question prompt correctly replacing list[rand] with the appropriate array item. However, using objects in my array, my prompt says "What kind of equipment is [object Object]?.
My end goal is for the user to enter the appropriate one- or two-letter response (M for Microphone, C for Console, O for Outboard Gear, T for Tape Machine, S for Software, and CH for Computer Hardware) where upon entering the successful letter(s) yields an alert that displays both the object's answer and desc. My n00b instinct tells me this second part should be an if/else statement in the form of
if (question == list[rand.answer]) {
alert("Correct, Answer: " + list[rand.answer] + ", a " + list[rand.desc] + "!");
}
else {
alert("Wrong, try again.");
}
but I'm very certain that this isn't the right way to access these object properties.
So, again, my question has two parts:
How can I access the objects in my array so that they properly appear in my question prompt, and
How can I access the properties of the randomely selected object in an if/else statement?
I'm sure some piece of logic is escaping me. Thanks for reading.
You want to use var question = prompt("What kind of equipment is " + list[rand].desc + "?");. list[rand] will yield you an object which has the structure {answer: "", desc: ""}, so you need to additionally access the description in your code.
Similarly, you want:
if (question == list[rand].answer) {
alert("Correct, Answer: " + list[rand].answer + ", a " + list[rand].desc + "!");
}
else {
alert("Wrong, try again.");
}
To access the property of an Object in Javascript you use dot notation, as is common with many languages that have Objects. list is an array of Objects, so when you type list[rand] you are returning one of those Objects. Once you have an Object, you simply need to use the dot notation to access whatever property it is you require, in this case either desc or answer.
So instead of
var question = prompt("What kind of equipment is " + list[rand] + "?");
try
var question = prompt("What kind of equipment is " + list[rand].desc + "?");
Placing the property you are trying to access outside the bracket. This solves your second question as well, simply change:
if (question == list[rand.answer]) {
alert("Correct, Answer: " + list[rand.answer] + ", a " + list[rand.desc] + "!");
to:
if (question == list[rand].answer) {
alert("Correct, Answer: " + list[rand].answer + ", a " + list[rand].desc + "!");
this fiddle will help demonstrate.

Categories