so I have a collection in mongoDB that has an structure like the following:
{
"_id": 129flaslkfja,
"number": 10
}
in this collection some elements have the number field set to 1 others to 2, others to 3, etc. in random order. I want to get an array that has in the first position all models with the number 1 in the next position all the models with the number 2 and so on. I know I can do this with a loop and a simple find or where but I want to know if there's a simpler, cleaner and more effective way in terms of performance.
I have tried with $group, $match but this is not what I want.
For example this is the data in my database:
[{
"_id": a1,
"number": 1
},
{
"_id": a2,
"number": 3
},
{
"_id": a3,
"number": 2
},
{
"_id": a4,
"number": 2
},
{
"_id": a5,
"number": 2
},
{
"_id": a6,
"number": 1
}]
So I want to group by number value like this:
[
[{
"_id": a1,
"number": 1
},
{
"_id": a6,
"number": 1
}],
[{
"_id": a3,
"number": 2
},
{
"_id": a4,
"number": 2
},
{
"_id": a5,
"number": 2
}],
[{
"_id": a2,
"number": 3
}]
]
You can also try below code
original_list.group_by(&:number).values
In ruby you can do:
original_list.group_by {|x| x[:number]}.values
It's not clear if you were asking for a Ruby solution, though.
Related
I want to filter based on the length of data. For example, I want to retrieve only the images array that contains more than 1 element. Something like that images.length > 6.
Is this possible using OData. Your help is much appreciated
{
"#search.score": 1,
"site": "core",
"images": [
{
"alt": "Quad"
}
]
}, ,{
"#search.score": 1,
"site": "ccc",
"images": [
{
"alt": "some"
}
]
},
{
"#search.score": 1,
"site": "ccc",
"images": [
{
"alt": "DePaul's Student Center"
},
{
"alt": "O'Malley"
},
{
"alt": "Campus"
},
{
"alt": " Campus"
},
{
"alt": "ith students"
},
{
"alt": "er"
},
{
"alt": "df"
},
{
"alt": "sdf"
},
{
"alt": "df"
},
]
A simpler and better solution is to populate your data with an additional property called ImageCount. If you submit your items via the Azure Search SDK, you can process them before submitting them to search. Add the image count to each item and then filter like normal.
$filter=ImageCount gt 6
First of all, I'm new to NEO4J and to CYPHER. So I'm twerking here and there to figure out to get the result I want.
Below is my graph. Let's say it's a simple family tree.
I have come up with this simple cypher query to fetch the direct descendants of the node
MATCH (p:Person {username: "SETHLORDM"})<-[r:CHILD_OF]-(p2)
RETURN {current: p, children: collect(p2)}
and the text version of the result is as below
The above is okay, but I want to get the text result as follows if it's doable with NEO4J.
[
{
"username": "SETHLORDM",
"location": "NO_LOCATION",
"children": [
{
"username": "TESTNODE_1",
"location": "LEFT",
"children": [
{
"username": "TESTNODE_3",
"location": "LEFT",
"children": []
},
{
"username": "TESTNODE_4",
"location": "RIGHT",
"children": []
}
],
},
{
"username": "TESTNODE_2",
"location": "RIGHT",
"children": [
{
"username": "TESTNODE_5",
"location": "RIGHT",
"children": []],
},
{
"username": "TESTNODE_6",
"location": "RIGHT",
"children": []],
}
],
}
],
}
]
Any help regarding this would be highly appreciated. Thank you
One way to approach it is using apoc.convert.toTree (using the plugin apoc).
This can create the tree structure that you are looking for. But, since your tree is bottom-up, the result will be same, meaning each node will point its parent. If you want to get the results as you want, using this method, you will have to change your relations.
For example, using this data:
MERGE (a:Person{key: 1, username: "SETHLORDM"})
MERGE (b:Person{key: 2})
MERGE (c:Person{key: 3})
MERGE (d:Person{key: 4})
MERGE (e:Person{key: 5})
MERGE (f:Person{key: 6})
MERGE (g:Person{key: 7})
MERGE (b)-[:CHILD_OF]-(a)
MERGE (c)-[:CHILD_OF]-(a)
MERGE (d)-[:CHILD_OF]-(b)
MERGE (e)-[:CHILD_OF]-(b)
MERGE (f)-[:CHILD_OF]-(c)
MERGE (g)-[:CHILD_OF]-(c)
and this query:
MATCH path = (p:Person {username: "SETHLORDM"})<-[r:CHILD_OF*..2]-(p2)
WITH collect(path) AS paths
CALL apoc.convert.toTree(paths)
YIELD value
RETURN value;
will give this result:
"_type": "Person",
"child_of": [
{
"_type": "Person",
"child_of": [
{
"_type": "Person",
"_id": 243,
"key": 5
},
{
"_type": "Person",
"_id": 242,
"key": 4
}
],
"_id": 240,
"key": 2
},
{
"_type": "Person",
"child_of": [
{
"_type": "Person",
"_id": 245,
"key": 7
},
{
"_type": "Person",
"_id": 244,
"key": 6
}
],
"_id": 241,
"key": 3
}
],
"_id": 239,
"key": 1,
"username": "SETHLORDM"
}
But changing the links to this:
MERGE (a)-[:CHILDREN]-(b)
MERGE (a)-[:CHILDREN]-(c)
MERGE (b)-[:CHILDREN]-(d)
MERGE (b)-[:CHILDREN]-(e)
MERGE (c)-[:CHILDREN]-(f)
MERGE (c)-[:CHILDREN]-(g)
And adjusting the query to:
MATCH path = (p:Person {username: "SETHLORDM"})-[r:CHILDREN*..2]->(p2)
WITH collect(path) AS paths
CALL apoc.convert.toTree(paths)
YIELD value
RETURN value;
Will provide:
{
"_type": "Person",
"_id": 246,
"children": [
{
"_type": "Person",
"_id": 247,
"children": [
{
"_type": "Person",
"_id": 249,
"key": 4
},
{
"_type": "Person",
"_id": 250,
"key": 5
}
],
"key": 2
},
{
"_type": "Person",
"_id": 248,
"children": [
{
"_type": "Person",
"_id": 252,
"key": 7
},
{
"_type": "Person",
"_id": 251,
"key": 6
}
],
"key": 3
}
],
"key": 1,
"username": "SETHLORDM"
}
Which is now similar to what you wanted...
Bonus: if you are using apoc, you can replace the MATCH query by apoc.path.expandConfig which should be more efficient to larger graphs.
I have a Hash like this, which should be "merged" to its uniq nested values
[
{
"slug": "color",
"values": [{ "slug": "amethyst" },
{ "slug": "coral" }],
},
{
"slug": "color",
"values": [{ "slug": "amethyst" }],
},
{
"slug": "power-source",
"values": [{ "slug": "110V"}],
}
]
at the same time it should count the duplicate values but made uniq in an items array:
{ "slug": "color",
"items": [
{
"slug": "amethyst",
"count": 2
},
{
"slug": "coral",
"count": 1
}]
},
{
"slug": "power-source",
"items": [
{
"slug": "110V",
"count": 1
}]
}
]
is there a "Rails method" to achieve this?
Thank you
I think there's nothing built-in in Rails that allows you to get such a custom requirement, but you can achieve it by playing around with different methods and their return values:
data
.group_by { |hash| hash[:slug] }
.transform_values do |values|
values
.flat_map { |vals| vals[:values] }
.group_by { |value| value[:slug] }
.transform_values(&:count)
end.map do |slug, items|
[slug, items.map { |item, count| {slug: item, count: count} }]
end.map { |slug, items| {slug: slug, items: items} }
# [{:slug=>"color",
# :items=>[{:slug=>"amethyst", :count=>2}, {:slug=>"coral", :count=>1}]},
# {:slug=>"power-source", :items=>[{:slug=>"110V", :count=>1}]}]
As you see, you can first group every hash in the array by their slug value, then transform the values that hash contains, mapping and flattening every array by their values key and then grouping to get their total.
After that you can just create the hash with its keys/values you need.
It might simplify the things a bit if you end up with a single hash, whose keys are the "slugs" and contains the items as its values.
For the Discovery REST api, the argument/parameter "return" controls which fields are returned.
So if I pass these arguments to the API
{
"query": named_sector,
"count": "10",
"filter": filter_dates,
"aggregation" : "term(docSentiment.type,count:3)"
}
my_query = discovery.query(my_disc_environment_id, my_disc_collection_id, qopts)
print(json.dumps(my_query, indent=2))
I get the following:
{
"matching_results": 14779,
"aggregations": [
{
"type": "term",
"field": "docSentiment.type",
"count": 3,
"results": [
{
"key": "positive",
"matching_results": 4212
},
{
"key": "negative",
"matching_results": 3259
},
{
"key": "neutral",
"matching_results": 152
}
]
}
],
"results": [
{
"id": "6389715fe7e7f711e0bc09d4f1236639",
"score": 1.3689895,
"yyyymm": "201704",
"url": "https://seekingalpha.com/article/4060446-valuation-dashboard-consumer-discretionary-update",
"enrichedTitle": null,
"host": "seekingalpha.com",
"text": "Valuation Dashboard: Consumer Discretionary - Update\n\nSummary\n\nValuation metrics in Consumer Discretionary.\n\nEvolution since last month.\n\nA list of stocks loo ....
and thousands of more lines. How do I restrict the output to the aggregations section? Is this an issue of me better handling the JSON structure that is returned?
thanks
If you change the count argument to 0, the returned JSON will only contain the aggregations.
Also, if you're using the Discovery web tooling, you can enter 0 for the "Number of results to return (Count)" field.
More details and an example can be found here: https://www.ibm.com/watson/developercloud/doc/discovery/using.html#building-aggregations
I am still trying to create an app where the user could transform his name or a word with chemical elements (like breaking bad logo).
The user will enter a word in a text field and when he'll submit it will return him the word with the corresponding chemical symbols if they match, or it will display the "raw" letters if they don't match.
ex: If no symbol matches I am keepking the initial entry so it could be: hello => He ll O (bold char represent the existing chemical symbols)
I know this could be done in js, but the challenge is ROR (btw I don't know any js...)
In an earlier question I had just a hash like:
symbols =
{"cr" => "Cr",
"sb" => "Sb",
"ag" => "Ag",
"ar" => "Ar",
"as" => "As",
"at" => "At",
"n" => "N",
"ba" => "Ba",
"bk" => "Bk"}
and I was using name.downcase.gsub!(Regexp.union(symbols.keys), symbols)to transform the user entry. Actually I need more datas... that's why I chosen the json file.
Like on this picture i will need to use:
"number"
"small"
"molar"
(and the "name" will appear in a caption below)
I have organized a .json file with all the symbols I may need in the app and stored it in my config/periodic_table.json (pasted just a sample cause it's very long).
1°) If a user enter "hello" how do I loop to search for the "he" hash and print the "name","number", "small" and the "molar"
2°) I will use the json as a database (I will use heroku to deploy) so do I have anything to transform for using json and pg together?
[ "symbols"
{
"h": {
"name": "Hydrogen",
"number": 1,
"small": "H",
"molar": 1.00794
},
"he": {
"name": "Helium",
"number": 2,
"small": "He",
"molar": 4.002602
},
"b": {
"name": "Boron",
"number": 5,
"small": "B",
"molar": 10.811
},
"c": {
"name": "Carbon",
"number": 6,
"small": "C",
"molar": 12.0107
},
"n": {
"name": "Nitrogen",
"number": 7,
"small": "N",
"molar": 14.0067
}
}
]
I will need to loop first with the symbols that contain 3 chars, then 2 then 1... shall i change anythin in the json, like an harray for the hashes that contains 3 chars, another for 2 chars , and for 1char?
Correct Json Format
[{
"symbols":{
"h":{
"name": "Hydrogen",
"number": 1,
"small": "H",
"molar": 1.0079
},
"he":{
"name": "Helium",
"number": 2,
"small": "He",
"molar": 4.002602
},
"b": {
"name": "Boron",
"number": 5,
"small": "B",
"molar": 10.811
},
"c": {
"name": "Carbon",
"number": 6,
"small": "C",
"molar": 12.0107
},
"n": {
"name": "Nitrogen",
"number": 7,
"small": "N",
"molar": 14.0067
}
}
}]