Using [Sequelize.Op.in] for json object arrays - javascript

I have a meta tag table which contains a tagId and a value.
I have an array of tagId,value objects
Eg : [{'tagId':2, 'value':33}, {'tagId':2, 'value':34}, {'tagId':1,
'value':34}, etc.. ]
My metaTag table consists of a virtual column which will return the {tagId,value} object for each entry in table. My question is how can I select rows with each {tagId, value} pair in the array.
In other words, I want to be able to do something like
[Sequelize.Op.in]:[{'tagId':2, 'value':33}, {'tagId':2, 'value':34}]
This doesn't work, however.
I might not have explained this well, English isn't my first language. Please ask if you need any clarification on the issue.

You can attain this by using Op.or. If I am not wrong you are trying
('tagId' = 2 and 'value' = 33) or ('tagId' = 2, 'value' = 34):
where: { [Sequelize.Op.or]: [{'tagId':2, 'value':33}, {'tagId':2, 'value':34}] }
You can add n number of values to the or array. As per your requirement.
if you want to do a in like this:
tagId in(2, 2) and value in (33, 34) then:
where: {'tagId':[2], 'value':[33, 34]}
You don't need the explicit Op.in for the array.

You can use there:
const myDeviceIds = [1, 2, 3, 4, 7, 9, 29];
const macroDevices = await MacroDevice.findAll({
where: {
deviceId: {
[Op.in]: myDeviceIds,
},
life: {
[Op.not]: null,
},
status: {
[Op.is]: null,
}
},
order: [
['id', 'DESC']
],
limit,
offset,
include: [
Macro,
Targets,
]
});

Related

Merging elements in my SQL query result Array with Javascript [duplicate]

This question already has answers here:
Group by array and add field and sub array in main array
(8 answers)
Closed 1 year ago.
As a newbie, I'm looking for the best approach to achieve the below:
Here is the Array I get from my DB query that contains a left join on the "class" table
[
{"legnumber":1,
"classcode" : "J"},
{"legnumber":1,
"classcode" : "Y"},
{"legnumber":2,
"classcode" : "J"}
]
And I would like to get something like this:
{
"legs": [
{
"legnumber" : 1,
"classes" : [
{"classcode" : "J"},
{"classcode" : "Y"}
]
},
{
"legnumber" : 2,
"classes" : [
{"classcode" : "J"}
]
}
]
}
Thanks a lot for your suggestions.
I'm using Sequelize in this project but I'm writing raw queries as I find it more convenient for my DB model.
Regards,
Nico
Hassan's answer is the more concise way to handle this, but here is a more verbose option to help understand what's happening:
const queryResults = [
{ legnumber: 1, classcode: 'J' },
{ legnumber: 1, classcode: 'Y' },
{ legnumber: 2, classcode: 'J' },
]
// create an object to store the transformed results
const transformedResults = {
legs: [],
}
// loop through each item in the queryResult array
for (const result of queryResults) {
// try to find an existing leg tha matches the current leg number
let leg = transformedResults.legs.find((leg) => leg.legnumber === result.legnumber)
// if it doesn't exist then create it and add it to the transformed results
if (!leg) {
leg = {
legnumber: result.legnumber,
classes: [],
}
transformedResults.legs.push(leg)
}
// push the classcode
leg.classes.push({ classcode: result.classcode })
}
console.log(transformedResults)
You can group your array items based on legnumber using array#reduce and then get all the values to create your result using Object.values().
const arr = [ {"legnumber":1, "classcode" : "J"}, {"legnumber":1, "classcode" : "Y"}, {"legnumber":2, "classcode" : "J"} ],
output = arr.reduce((r, {legnumber, classcode}) => {
r[legnumber] ??= {legnumber, classes: []};
r[legnumber].classes.push({classcode});
return r;
},{}),
result = {legs: Object.values(output)};
console.log(result);

How to use filter method for string key

I am new to this kind of problem.
I am getting an array object like this:
const obj = [{
"adId": 6,
"receiverid": 5,
"senderId": 7
},
{
"adId": 7,
"receiverid": 6,
"senderId": 5
}
]
console.log(obj.filter(item => item.adId > 5))
Now I want to apply filter method to apply some conditions over it.
I applied filter() method but the error comes that says
filter is not a function
But I am not getting how to apply filter for this kind of object data.
Suppose, you have this object that you mentioned
const obj = [
{"adId":6,"receiverid":5,"senderId":7},
{"adId":7,"receiverid":6,"senderId":5}
];
If I correctly understood your question, now you want to filter only some of the object that fit according to your condition, so for that you apply filter like this
const filteredObjects = obj.filter((individualObject) => {
if (individualObject['adId'] > 6) {
return true;
}
});
so now our filteredObjects will be an array like below
filteredObjects = [{"adId":7,"receiverid":6,"senderId":5}]
This code works. A couple of things though. The data type is an array of objects, not an object, and your filter condition didn't filter out either object. If you change it to item.adId > 6 it will.
const arr = [{
"adId": 6,
"receiverid": 5,
"senderId": 7
},
{
"adId": 7,
"receiverid": 6,
"senderId": 5
}
]
console.log(arr.filter(item => item.adId > 6))

MongoDB compare array_A with documents $match array_B, and return Array_C (array_A less array_B)

I am trying to find an array_C, which contains only items in array_A that do not appear in array_B. But I'm trying to use $match in aggregate to represent array_B.
Example:
array_A = [1, 2, 3]
array_B = [2, 4, 6, 8, 10]
array_C = [1, 3]
And doing this using Model.aggregate() using $match criteria.
Here is how I think the code should work:
Model.aggregate(
[{
$match: {
"u_oid": mongoose.Types.ObjectId(req.params.u_oid),
"t_oid": mongoose.Types.ObjectId(req.params.t_oid)
}
},
{
"$project" : { "array_C" : {"$filter": { "input": array_A, "$cond": {"$not": { "$in": "$match"} }}}}
}]
).exec((err, doc) => {
console.log("The doc is: "+JSON.stringify(doc))
})
In this case, I'm using "$match" to represent array_B.
The console log returns: undefined.
edit
Here is a more detailed example of the desired output:
Note: each array is made up of ObjectIds:
array_A = ["5f522bc55dd8993e58283526","5f522ab45dd8993e58283521","5f522ba65dd8993e58283525","5f522a5e5dd8993e5828351f"]
array_B = ["5f522bc55dd8993e58283526","5f522ab45dd8993e58283521"]
array_C = ["5f522ba65dd8993e58283525","5f522a5e5dd8993e5828351f"]
array_A comes from another API. I am trying to compare it to a different doc set, and find which ones don't have a match.
Thanks for comments.
Maybe this one?
{"$project": {array_C: { $setDifference: [ "$array_A", "$array_B" ] } }}
Mongo Playground

Loop through array of objects, check for a matching parameter and add the matching object to new array

I'm new to JS and React and I'm a little stuck here. I've searched through SO but I'm having trouble finding a solution with an explanation that works.
Here are my arrays.
The first array is pretty simple.
[1, 3, 4,]
The second looks like this.
[
{
id: 1,
title: Title 1,
},
{
id: 2,
title: Title 2,
},
]
What I'd like to do is search the second array and if I can find an id that matches a value in the first array, add the object from the second array to third, new array.
I've tried a number of things and I'm sure there's a relatively easy way to do this with a forEach loop or lodash but I'm coming up blank.
Any help and explanations would be greatly appreciated.
Thanks,
Your second array is not valid. You have to wrap the string values with quotes.
You can use Array.prototype.filter()
The filter() method creates a new array with all elements that pass the test implemented by the provided function.
and Array.prototype.includes()
The includes() method determines whether an array includes a certain element, returning true or false as appropriate.
Try the following way:
var arr1 = [1, 3, 4,];
var arr2 = [
{
id: 1,
title: 'Title 1',
},
{
id: 2,
title: 'Title 2',
},
];
var res = arr2.filter(i => arr1.includes(i.id));
console.log(res);

Extracting data from a complex array without lots of FOR loops

I have a fairly complex array generated from Google's natural language API. I feed it a paragraph of text and out comes lots of language information regarding such paragraph.
My end goal is to find "key words" from this paragraph, so, to achieve this I want to put all the "entities" into a flat array, count the duplicates, and then consider words with the highest amount of duplicates to be "key words". If it doesn't find any then I'll cherry pick words from entities I consider most significant.
I already know the entities that could exist:
var entities = [
'art',
'events',
'goods',
'organizations',
'other',
'people',
'places',
'unknown'
];
Here is an example structure of the array I'm working with.
input = [
{
language: {
entities: {
people: [
{
name: "Paul",
type: "Person",
},
{
name: "Paul",
type: "Person",
},
],
goods: [
{
name: "car",
type: "Consumer_good",
}
], //etc
}
}
}
];
output = ["Paul", "Paul", "car"...];
My question is - what is the best way to convert my initial array into a flat array to then find the duplicates without using a whole bunch of FOR loops?
There is no way around loops or array functions if you work with dynamic input data.
You can access all the values using this format:
input[0]["language"]["entities"]["people"][0].name
input = [
{
language: {
entities: {
people: [
{
name: "Paul",
type: "Person",
},
{
name: "Paul",
type: "Person",
},
],
goods: [
{
name: "car",
type: "Consumer_good",
}
], //etc
}
}
}
];
console.log(input[0]["language"]["entities"]["people"][0].name);
Then you could do something like this:
for (var entry in input[0]["language"]["entities"]) {
console.log(entry);
}
OR, if I understood you wrong,
You can use this to turn the javascript Object into an array using this (requires jquery):
var myObj = {
1: [1, 2, 3],
2: [4, 5, 6]
};
var array = $.map(myObj, function(value, index) {
return [value];
});
console.log(array[0][0]);
console.log(array[0]);
console.log(array);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
This will output
1
[1, 2, 3]
[[1,2,3],[4,5,6]]
You could iterate through input.language.entities in a recursive way and collect all the .name properties into an array. Then you have only one for loop :-).
After doing that, you can iterate through it to find the duplicates. If you sort it alphabetical before it is easier (if two or more consecutive entries are equal, there are duplicates).
But it could be a bit dangerous if google changes the api or if it delivers crap data because of a malfunction.
Isn't input.language.entities already flat enough to work with it?
I ended up doing something like this. It's not pretty but it gets the job done.
var result = [];
var known_entities = ['art','events','goods','organizations','other','people','places','unknown'];
for(i=0; i < known_entities.length; i++){
var entity = known_entities[i];
if(language.entities[entity]){
for(var j in language.entities[entity]){
var word = language.entities[entity][j].name
result.key_words.push(word);
}
}
}

Categories