I' ve a big list of products (they are ink cartidges and toner) stored in a couchdb, for every document i've got several fields, and one particular field called "models" that is a multidimensional array like this:
"models": {
"Brother": {
"HL": [
"5200",
"5240",
"5240 DN",
"5240 DNLT",
"5240 L",
"5250 DN",
"5250 DNHY",
"5250 DNLT",
"5270 DN",
"5270 DN 2 LT",
"5270 DNLT",
"5280 DW",
"5280 DWLT"
]
},
"": {
"MFC": [
"8460 DN",
"8460 N",
"8860 DN",
"8860 N",
"8870 DW"
],
"DCP": [
"8060",
"8065 DN"
]
},
"Lenovo": {
"": [
"LJ 3500",
"LJ 3550",
"M 7750 N"
]
}
},
I've to do several things with this data, starting with fixing a little problem that i've got while they was written, if you look at the example that i've posted, the second and the third brother serie has an empty array string instead of the "brand" value that should be "Brother"... i've many records that miss the "brand" key for certain series, and this should be set to the previous serie brand, i.e. the "MFC" serie should has the top level key set to "Brother" that is the key of the previous serie.
I can do this using a view in couchdb?
After doing that i need to obtain a list of unique models using another view with every product associated to them.. in other words i've to select all of my products using the last level of the multidimensional array "models" as key (including also brand and serie values as secondary result for futher sorting and filtering) and all the products that contain that certain model as value.
An output like this:
key: "Brother, HL, 5200" - value: "id_product1, id_product2, idproduct3, etc."
Before i start to reading all documentation present on the earth can someone explain me if this thin is at least doable?
Thanks in advance...
Related
I am using knex to create queries for my express server.
I have two tables as follows:
I need to create a join on the two tables through the "owner_id" foreign key. Then I need to return objects containing an "avg" key, representing the average of all ratings by owner. And an "owner_name" key representing the owner of the restaurant. Finally I need to order by owner_name.
Here is what I have in my knex query so far:
function listAverageRatingByOwner() {
return knex("restaurants as r")
.join("owners as o", "r.owner_id", "o.owner_id")
.select("r.rating as avg", "o.owner_name")
.orderBy("o.owner_name")
}
I have also tried:
return knex("restaurants as r")
.join("owners as o" , "r.owner_id", "o.owner_id")
.select("r.rating as avg", "o.owner_name")
.groupBy("o.owner_name")
.avg("r.rating")
.orderBy("o.owner_name")
and I do get data back from this, but the owners are not grouped together by name with the average corresponding to that specific owner.
Here is what I am getting back :
enter image description here
And here is what I am expecting to be returned:
{
"data": [
{
"avg": 3.8200000000000003,
"owner_name": "Amata Frenzel;"
},
{
"avg": 2.25,
"owner_name": "Curtice Grollmann"
},
{
"avg": 2.45,
"owner_name": "Daffy Furzer"
}
]
}
Any help on how to group by owner_name with the avg rating for that owner would be awesome!!
here are my migrations for the two tables:
Owners
Restaurants
Seems to me you're getting back precisely what you're querying. You've got some restaurants, you've got some owners, you're doing a join between them and pulling the owner name and rating.
You indicate that you're trying to instead group by the name and then calculate an average from each of the ratings values for each restaurant, so you need to explicitly take an average of the ratings field and then provide a groupBy for the owner name as in the following:
return knex("restaurants as r")
.join("owners as o" , "r.owner_id", "o.owner_id")
.avg("r.rating as avg")
.select("avg", "o.owner_name")
.groupBy("o.owner_name")
.orderBy("o.owner_name")
Your second example was nearly right, but you were discarding the avg aggregate method output when you were selecting directly from the ratings. Here, we do the average aggregate and call that output 'avg', then select on that alias and the owner_name for the result.
I'm trying to find the best way to group by category and iterate products in O (n) to get some insights from the categories.
I have the sample data:
[
{
"code": 25754,
"description": "ADAPTADOR BLUETOOH USB RECEPTOR DE AUDIO P2",
"price": 5.0,
"stock": 10,
"category": {
"id": 1,
"name": "Adapters"
}
},
{
"code": 20212,
"description": "ADAPTADOR CONECTOR HDMI FEMEA L / FEMEA",
"price": 2.8,
"stock": 20,
"category": {
"id": 2,
"name": "Eletronics"
}
},
]
I need to invert the relationship, having a list of categories with corresponding products, and for that i wrote this solution
function group_by_categories(products) {
const categories = {}
for (const product of products) {
const { category, ...cleanedProduct } = product
categories[category.id] = categories[category.id] || category
categories[category.id].products = categories[category.id].products || []
categories[category.id].products.push(cleanedProduct)
}
return Object.values(categories)
}
// returns
[
{ id: 1, name: 'Adapters', products: [ [Object] ] },
{ id: 2, name: 'Eletronics', products: [ [Object] ] }
]
But I am struggling in two things.
Is it the best way to reverse the relationship? How can I replicate this in another language like C, where I have no objects to use as unique keys?
Once you have this type of data, the only way to iterate categories and products (see how many items a category has, for example) is in O (n²)?
I appreciate all the help, even if you can only answer one question. Also, sorry for my bad English, I'm trying to be as clear as possible here.
So you have 3 issues. 1) Use the code/id as keys instead, 2) Use sets instead of arrays, and 3) use an appropriate data structure to avoid duplicating work that you've already done.
You really just want to map the connections not all the data. I believe code is probably unique to the product, so that is your key. Your category id is also likely unique, so you only need to consider that. The mapping structures should only concern themselves with the minimal amount of unique data. This may increase performance a fair bit as well as the amount of data that get's copied is probably 1/10 to 1/100 of yours in terms of # of characters (of course translating that exactly to time saved is difficult). Of course, that's a minor point compared to the O(N^2) performance, but just that would likely speed things up by a bit by that alone.
You should be using sets as well as the hash (object). Idea here is O(1) lookup, O(1) size check, O(1) inclusion test (IE: Does the category X have code Y in it?), and O(1) mapping back to the original data (code Y is a product with this information).
The other key thing is you really just want to map the connections not all the data. I believe code is probably unique to the product, so that is your key. Your category mapping structure should only concern itself with the minimal amount of unique data (this will increase performance by a lot as well).
Keep in mind, if you have access to an actual database that is probably the more ideal solution, 95% or so of the time once you start wanting to do more complex queries. I would say you almost certainly should be using one, there's probably a database that will suit your needs.
That being said, what you need is this if you don't need to go too far with your queries. It looks like you need to answer these three questions:
Given the code, what is the record (sample data)? This is just a simple code:product object. IE: {25754: {code: ..., price: ..., stock: ..., ...}, {20212: {code: ..., price: ..., stock: ..., ...}}
Given a category, what are the codes in that category? In this case you have a category_id:set(codes) lookup. Very important that you add codes to a set and not a list/array. Sets have O(1) to add/delete/inclusion, while lists/arrays have O(1) add, O(N) delete and O(N) inclusion check.
Given a category, how many are in that category? This is just a data[category].size check (length instead of size in some languages).
Main thing is to use dictionaries and sets for performance.
Time to build the lookups is likely O(P) where P is the total number products. Performance for the queries should be O(1) for each one you need to do.
To avoid O(N^2) performance the lookup should only be calculated once. Should you need to add/remove products from categories, you should adjust the lookup itself and not rebuild it every time. This may mean storing it in a database, building when you first run the app and keeping it in memory, or if the # of products isn't too much, building it at each request (by only using the minimal amount of data to build it, it may be more practical). Generally speaking, even with 1000 products, it should take probably milliseconds to build the category lookup and iterate over them.
Basically your category code should look like his after you've written out the methods.
...
category_lookup = build_category_lookup() # O(P)
product_lookup = build_product_lookup() # O(P)
...
products_for_category = product_lookup[category_id] # O(1)
products_count = products_for_category.length # O(1) | C: sizeof(products_for_category)
...
(Mostly code in ruby these days, so snake_case)
I have a JSON file containing:
{"mapping": [
[
"london",
"51.18452",
"-0.150839",
"2016-04-19"
],
[
"london",
"52.6127",
"-2.02296",
"2016-04-21"
],
[
"london",
"53.334",
"-6.2761",
"2016-04-15"
]
}
Within my HTML I wish to have a range slider like this:
[]-----------------
oldest recent
In this scenario, the oldest JSON data should be shown, so
"london",
"53.334",
"-6.2761",
"2016-04-15"
And as the user slowly moves the range slider closer to the right end, more recent data should be shown..
----------------[]-
oldest recent
displaying..
"london",
"52.6127",
"-2.02296",
"2016-04-21"
I have many other values within the JSON file, I just used these three examples to show the format of the file. I am creating a heat map and whilst the slider moves along, the heat map should change to generate different points. Thanks for any help with this!
Turning the arrays into objects is optional, but it is much easier to reference properties like that, also it allowed us to convert the date string into a date object which has a number value to compare with.
const objectMapping = data.mapping.map(element => ({city:element[0], latitude:element[1], longitude:element[2], date:new Date(element[3])}));
Now that you have objects rather than an array, you can just say Array.sort on the date object where if b is higher than a, then b will come before a in the list
const sortedMapping = objectMapping.sort((a, b) => b.date - a.date);
Then sortedMapping[0] = oldest date
I have a form that has three fixed questions, each question is followed by two drop down control for a user to select.
Since my number of questions are fixed and will remain fixed , I am not using ng-repeat to render my questions.
In the end, I want my structure to be represented as
Attendee
-Name
-Email
-EventCollection
---Event1
----Event1Name
----IsAccepted
----TotalAdults
----TotalChildren
---Event2
----EventName
----IsAccepted
----TotalAdults
----TotalChildren
ng-model for my event fields for e.g. is set as
indata.im.EventList[0].IsAccepted, indata.im.EventList[1].IsAccepted and indata.im.EventList[2].IsAccepted
Issue I am facing here is that the JSON emitted has additional index attached to it. "0" , "1", "2". How to remove this index numbers that are getting added here
{
"Name":"Kunal",
"EventList":{
"0":{
"TotalAdults":"3",
"TotalChildren":"2",
"IsAccepted":"1",
"EventName":"Sangeet"
},
"1":{
"TotalAdults":"1",
"TotalChildren":"2",
"IsAccepted":"1",
"EventName":"Marriage"
},
"2":{
"TotalAdults":"2",
"TotalChildren":"1",
"EventName":"Reception"
}
}
}
I've problem sorting my nested array, says I've json like this
var orders = [{
'orderId': 1,
'sales': [{
'salesNumbers': 3
}]
}, {
'orderId': 2,
'sales': [{
'salesNumbers': 4
}]
}];
and I wish I can sort orderId base on salesNumbers. You may say it's impossible or I made a mistake by putting sales as array but it contain only 1 object which is salesNumbers. That's not a mistake, I just do not want to simplify my problem.
so it's possible to, without changing the data structure, sort orderId base on salesNumbers?? My app demo http://jsfiddle.net/sq2C3/
Since you say the sales array only has one item in it, you can order by salesNumbers like this:
orderBy:'sales[0].salesNumbers'
Here is an update of your fiddle: http://jsfiddle.net/wittwerj/sq2C3/2/