getting distinct values from result set in taffyDB - javascript

I have a TAFFYDB database that consists of 4 fields:
clientID
cTech
arDate
active
What I want is a unique list of "cTech" for a certain clientID inside of a range of dates.
I can match clientID and dates like this:
var ret=clientTechsDB([{
"clientID":cFrom.toLowerCase(),
"arDate":{gte:sDfrom},
"arDate":{lte:sDto},
}]).get();
That returns the array "ret", but ret has many duplicated cTech values.
I tried
var ret=clientTechsDB([{
"clientID":cFrom.toLowerCase(),
"arDate":{gte:sDfrom},
"arDate":{lte:sDto},
}]).get().distinct("cTech");
but that generates and error "get(...).distinct is not a function"
I can iterate through and filter out duplicates but I was hoping to do it in a taffyDB query.
How?

You don't need "get" when using distinct. The correct syntax is:
var ret=clientTechsDB([{
"clientID":cFrom.toLowerCase(),
"arDate":{gte:sDfrom},
"arDate":{lte:sDto},
}]).distinct("cTech");

Related

Sequelize how to return result as a 2D array instead of array of objects?

I am using Sequelize query() method as follows:
const sequelize = new Sequelize(...);
...
// IMPORTANT: No changed allowed on this query
const queryFromUser = "SELECT table1.colname, table2.colname FROM table1 JOIN table2 ON/*...*/";
const result = await sequelize.query(queryFromUser);
Because I am selecting two columns with identical names (colname), in the result, I am getting something like:
[{ "colname": "val1" }, { "colname": "val2" }...], and this array contains values only from the column table2.colname, as it is overwriting the table1.colname values.
I know that there is an option to use aliases in the SQL query with AS, but I don't have control over this query.
I think it would solve the issue, if there was a way to return the result as a 2D array, instead of the array of objects? Are there any ways to configure the Sequelize query that way?
Im afraid this will not be possible without changes in the library directly connecting to the database and parsing its response.
The reason is:
database returns BOTH values
then in javascript, there is mapping of received rows values to objects
This mapping would looks something like that
// RETURNED VALUE FROM DB: row1 -> fieldName:value&fieldName:value2
// and then javascript code for parsing values from database would look similar to that:
const row = {};
row.fieldName = value;
row.fieldName = value2;
return row;
As you see - unless you change the inner mechanism in the libraries, its impossible to change this (javascript object) behaviour.
UNLESS You are using mysql... If you are using mysql, you might use this https://github.com/mysqljs/mysql#joins-with-overlapping-column-names but there is one catch... Sequelize is not supporting this option, and because of that, you would be forced to maintain usage of both libraries at ones (and both connected)
Behind this line, is older answer (before ,,no change in query'' was added)
Because you use direct sql query (not build by sequelize, but written by hand) you need to alias the columns properly.
So as you saw, one the the colname would be overwritten by the other.
SELECT table1.colname, table2.colname FROM table1 JOIN table2 ON/*...*/
But if you alias then, then that collision will not occur
SELECT table1.colname as colName1, table2.colname as colName2 FROM table1 JOIN table2 ON/*...*/
and you will end up with rows like: {colName1: ..., colName2: ...}
If you use sequelize build in query builder with models - sequelize would alias everything and then return everything with names you wanted.
PS: Here is a link for some basics about aliasing in sql, as you may aliast more than just a column names https://www.w3schools.com/sql/sql_alias.asp
In my case I was using:
const newVal = await sequelize.query(query, {
replacements: [null],
type: QueryTypes.SELECT,
})
I removed type: QueryTypes.SELECT, and it worked fine for me.

Extract JSON table from JSON string element

I get this JSON in response from server:
{
"tab":[
"[[\"2018\",11,\"19\",\"16\",\"13\"],null,null,null,null,null,\"40\"]",
"[[\"2018\",11,\"19\",\"16\",\"19\"],null,null,null,null,null,\"56\"]",
"[[\"2018\",11,\"19\",\"16\",\"21\"],null,null,null,null,\"57\",null]"
]
}
I know, that I can get first element of tab table returned using $.tab[1]. The returned element is a string that holds a table - first element of this table is another table holding a date. The question is what JSON Path expression should I use in order to extract year value from the inner table or one of those numbers at the end (40, 56, 57)?
I'm not sure what you mean when you say you can get the first element with $.tab[1]. Are you using jQuery? Even so, that doesn't seem to make any sense. Regardless, you can parse those inner tables and access them normally as arrays:
var results = {
"tab":[
"[[\"2018\",11,\"19\",\"16\",\"13\"],null,null,null,null,null,\"40\"]",
"[[\"2018\",11,\"19\",\"16\",\"19\"],null,null,null,null,null,\"56\"]",
"[[\"2018\",11,\"19\",\"16\",\"21\"],null,null,null,null,\"57\",null]"
]
};
// you can refactor this as a method for more convenient usage, this is just a demo
var row = JSON.parse(results.tab[0]);
// now you just have a multi-dimensional array, use it as normal
console.log(row[0][0]); //year
console.log(row[6]); //number

find value in complex object javascript

Basically I have a complex object that retrieves the GPT API (google publisher tag) with this function:
googletag.pubads().getSlots();
The object value is something like this:
I need to know if there is a way to compare the value of each property with an X value without getting a problem of recursivity (because the object is huge and i need to to that validation several times)
Also, I tried to convert that object into a JSON with JSON.stringify(), and then tried to get the value with a regex, faster, but with this option, I have the problem with Cyclic Object Value.
Any suggestions ?
it's more simple. try it to convert it into an array and later use a filter for comparative with your value.
var objGoogle = {};
var arrayObjectGoogle = [objGoogle];
var filter = arrayObjectGoogle.filter(function(obj){
obj.yourAttr == yourValue; });
this will give you a second array with the values found it. later, index the array for pick up the value do you need.

Taffydb dynamic like 'and' query

I recently started working with taffydb. Assuming I have this as my data
db= TAFFY([
{OrderNo:'prod1',range: 3,description:'one two'},
{OrderNo:'prod2',range: 2,description:'one two three'},
{OrderNo:'prod3',range: 2,description:'one three two'},
{OrderNo:'prod4',range: 6,description:'one two four three'},
{OrderNo:'prod5',range: 5,description:'three'},...
if I wanted to write a query to find all records with "one two" and "three" I'd do something like
db({description:{likenocase:"one two"}},{description:{likenocase:"three"}}).get()
this would return products 2 and 4. Unfortunately I can't figure out how to do this with a dynamic query that will have an unknown number of variables to search for. I'm doing this to let the user search for their own supplied words.
Anyone got any ideas?
As a precursor, this will not be the best answer to your problem. But it will work. :)
So the user will have the option of searching a database with an "unknown number of variables". Let's add a maximum amount of variables--perhaps 10?
Now we catch all the user's search variables in an array:
// Create a dynamic array
var userSearchVars = [];
// Fill the array from 10 HTML input type=text fields
// You can fill your array however you fancy. This is just one example!
$("#myForm input[type=text]").each(function() {
userSearchVars.push( $(this).val());
}
// Note: by default an empty input will return the empty string: ""
Using your code snippet, just query the database with the array:
db(
{description:{likenocase:userSearchVars[0]}},
{description:{likenocase:userSearchVars[1]}},
{description:{likenocase:userSearchVars[2]}},
{description:{likenocase:userSearchVars[3]}},
{description:{likenocase:userSearchVars[4]}},
{description:{likenocase:userSearchVars[5]}},
{description:{likenocase:userSearchVars[6]}},
{description:{likenocase:userSearchVars[7]}},
{description:{likenocase:userSearchVars[8]}},
{description:{likenocase:userSearchVars[9]}}
).get()
Adapting #Jacob-IT's answer so that its dynamic. Used Taffy for the first time tonight and just discovered you can pass an array of objects as the query argument.
// Create a dynamic array
var userSearchVars = [];
// Fill the array from 10 HTML input type=text fields
// You can fill your array however you fancy. This is just one example!
$("#myForm input[type=text]").each(function() {
// This is my edit - push the whole query on to the array.
userSearchVars.push({description:{likenocase: $(this).val() }});
}
// Then pass the whole query array in...
db( userSearchVars ).get()
Tested the above - and it worked for me.
You can do it like this
let items = [];
items.push({description:{likenocase:"one two"}});
items.push({description:{likenocase:"three"}});
db(...items).get()

mongodb query script by js. with condition as an array to iterate

db = db.getSiblingDB("aqua") //same as use otherdb
var legalStatus=["initiate","process","complete","replicating","failed","offline_complete","offline_fail","invalid"];
var replicas=db.aquaObject.find({"replicas":{$ne:null},"replicas.status":{$nin:legalStatus}});
replicas.forEach(
function(t){
db.aquaObject.update(t,{$set:{"replicas.0.status":"initiate"}});
});
this is the script that I wrote. But the condition in the find method: "replicas.status",here the replicas is an array. I want to iterator all the replicas and filter each one's status. So I believe what I write is not correct. How can I refine it? Thanks.

Categories

Resources