How to print Grails params without the flattened keys - grails

params in Grails is a GrailsParameterMap that automatically builds up sub-Maps by splitting parameter names that contain dots.
For example, if my query string is ?one.two.three=hello then Grails gives me a params variable that contain both the flattened (original) and the re-structured values:
params == [
"one.two.three": "hello",
one: [
"two.three": "hello",
two: [
three: "hello",
],
],
// plus "controller parameters"
]
If we ignore the additional "controller parameterss", such as controller and action, how can I get a clean version of this, withouth the original flattened parameters?
[
one: [
two: [
three: "hello"
]
]
]

Related

Use mongoid to count array size with aggregate

I'm trying to translate aggregation from the MongoDB shell to ruby code that uses Mongoid as ODM.
I have some documents like this (very simplified example):
{
"name": "Foo",
"tags": ["tag1", "tag2", "tagN"]
},
{
"name": "Bar",
"tags": ["tagA", "tag2"]
},
...
Now I'd like to get all documents with the name field and the total number of tags for each.
In the MongoDB shell I can achieve it using aggregation framework like this:
db.documents.aggregate(
{$project: {name: 1, tags_count: {$size: $tags}}
)
And it will return:
[{"name": "Foo", "tags_count": 3},
{"name": "Bar", "tags_count": 2}]
Now the frustrating part, I'm trying to implement the same query inside a rails app using Mongoid as ODM.
The code looks like (using rails console):
Document.collection.aggregate(
[
{'$project': {name: 1, tags_count: {'$size': '$tags'}}}
]
).to_a
And it returns the next error:
Mongo::Error::OperationFailure: The argument to $size must be an Array, but was of type: EOO (17124)
My question is: How can I make Mongoid understand that $tags makes reference to the correct field? Or what I'm missing from the code?
Thanks
It looks like there is data which does not consistently have an array in the field. For this you can use $ifNull to place an empty array where none is found and thus return the $size as 0:
Document.collection.aggregate(
[
{'$project': {name: 1, tags_count: {'$size': { '$ifNull': [ '$tags', [] ] } } }}
]
).to_a
Alternately you could simply skip where the field is not present at all using $exists:
Document.collection.aggregate(
[
{'$match': { 'tags_count': { '$exists': true } } },
{'$project': {name: 1, tags_count: {'$size': '$tags'}}}
]
).to_a
But of course that will filter those documents from the selection, which may or may not be the desired effect.

neo4jClient create node with dynamic label using paramters

I am building an app that give users the ability to construct there own graphs. I have been using parameters for all queries and creates. But when I want to give users the ability to create a node where they can also Label it anything they want(respecting neo4j restrictions on empty string labels). How would I parameterize this type of transaction?
I tried this:
.CREATE("(a:{dynamicLabel})").WithParams(new {dynamicLabel = dlabel})...
But this yields a syntax error with neo. I am tempted to concatenate, but am worried that this may expose an injection risk to my application.
I am tempted to build up my-own class that reads the intended string and rejects any type of neo syntax, but this would limit my users a bit and I would rather not.
There is an open neo4j issue 4334, which is a feature request for adding the ability to parameterize labels during CREATE.So, this is not yet possible.
That issue contains a comment that suggests generating CREATE statements with hardcoded labels, which will work. It is, unfortunately, not as performant as using parameters (should it ever be supported in this case).
I searched like hell and finally found it out.
you can do it like that:
// create or update nodes with dynamic label from import data
WITH "file:///query.json" AS url
call apoc.load.json(url) YIELD value as u
UNWIND u.cis as ci
CALL apoc.merge.node([ ci.label ], {Id:ci.Id}, {}, {}) YIELD node
RETURN node;
The JSON looks like that:
{
"cis": [
{
"label": "Computer",
"Id": "1"
},
{
"label": "Service",
"Id": "2"
},
{
"label": "Person",
"Id": "3"
}
],
"relations": [
{
"end1Id": "1",
"Id": "4",
"end2Id": "2",
"label": "USES"
},
{
"end1Id": "3",
"Id": "5",
"end2Id": "1",
"label": "MANAGED_BY"
}
]
}
If you are using a Java client, then you can do it like this.
Node node = GraphDatabaseService.createNode();
Label label = new Label() {
#Override
public String name() {
return dynamicLabelVal;
}
};
node.addLabel(label);
You can then have a LabelCache which will avoid Label object creation for every node.

Submitting an array of arrays to grape rails

managed to submit a simple array to my grape api following this tip
testing rails grape API with curl, params array
Building a simple workout tracker that generates a graph at the end, through this array of workouts, which should be passed with their keys I guess.
But since what i'm trying to do is a 2D array, i have this output, the type is set to Array[Array], this is the call that i'm currently using
curl --data 'workouts_array[]=1&workouts_array[]=2&workouts_array[]=3' http://localhost:3000/api/v1/workouts/workout.json
And it returns
{
"workouts_array": [
[
"1"
],
[
"2"
],
[
"3"
]
]
}
But i wish to pass something like workouts_array[]=[1][2][3]&workouts_array[]=[4][5][6]
so it returns
{
"workouts_array": [
[
"time": "1", "distance": "2", "calories": "3",
],
[
"time": "4", "distance": "5", "calories": "6",
]
]
}
Thank you for any help, I guess it's just my poor way of using curl
I'm not sure that I correctly understood you but
for your case you can use this query
workouts_array[0]=1&workouts_array[0]=2&workouts_array[0]=3
&workouts_array[1]=4&workouts_array[1]=5&workouts_array[1]=6
it should return smth similar to:
[
[
"1",
"2",
"3"
],
[
"1",
"2",
"3"
]
]
this is array of arrays.
you says you set the type Array[Array] but wanna see the array of hashes. it's kinda different.
BTW, I prefer use JSON payload for those things.

Indexing into JSON

This seems like it should be a very easy question but I'm having some trouble with it. I'm creating my own JSON and I need to index into it in order to seed by database. I've indexed into JSONs before with very little difficulty, but for some reason I can't index into my own. That makes me think that there might be an issue with my JSON itself, but I can't see anything that would cause an issue. I appreciate your assistance!
My JSON:
{
"workouts": [
{
"level": "1",
"exercises": [
{
"name": "box jumps",
"difficulty": "3",
"reps": "10",
"sets": "3",
"requirements": [
"sturdy box at least two feet high"
],
"body-part": "quadriceps",
"description": "Plant both feet should length apart and jump onto the box. Once on the box, stand fully upright.",
"pounds": "1"
},
{
"name": "v-press",
"difficulty": "4",
"reps": "12",
"sets": "3",
"requirements": [
"mat"
],
"body-part": "abdominals",
"description": "Lie flat on the ground, then raise your legs and arms slightly off the matt.",
"pounds": "1"
}
]
},
{
"level": "2",
"exercises": [
{
"name": "assisted pullups",
"difficulty": "1",
"reps": "12",
"sets": "3",
"requirements": [
"Assisted Pullup Machine"
],
"body-part": "biceps",
"description": "Kneel on the machine and adjust the weight to your needs",
"pounds": "50"
},
{
"name": "assisted dips",
"difficulty": "1",
"reps": "12",
"sets": "3",
"requirements": [
"Assisted Dips Machine"
],
"body-part": "triceps",
"description": "Kneel on the machine and adjust the weight to your needs",
"pounds": "50"
}
]
}
]
}
In pry, I do the following:
require "json"
f= File.open("workout.json")
mylist = JSON.parse(f.read)
When I try to index in, I get various errors (syntax error, no method errors, nil). Below are some examples of indexing I have attempted.
mylist.workouts
mylist[:workouts]
mylist[0]
mylist[:workouts][0][:level]
Thanks in advance!
The keys in the Hash after parsing the JSON data are strings not symbols. Try this :
mylist['workouts']
mylist['workouts'][0]['level']
A couple of points to remember :
Strings and Symbols are not interchangeable as keys in a Hash. They both are different objects and hence different keys.
To get the behaviour of the params in Rails controller where strings and symbols are interchangeable you need to instantiate an instance of HashWithInDifferentAccess. It is a separate utility class provided by Rails and is not part of the Ruby stdlib
The gem jbuilder is not a JSON parser. It is a JSON creator. It is used to create JSON structures from Ruby objects, used mostly in writing views for JSON responses. It is analogous to how ERB is used for HTML responses.
JSON has been part of Ruby stdlib for some time now (i.e. JSON parsing and serialization does not require any additional gems).

apache camel: Dynamic router is calling the same end point for multiple times in a single request

I have configured the dynamic router in the receiver router like below,
dynamicRouter(method("com.eg.DynamicIncomingRoute"), "getIncomingRoute"))
But it is redirecting the request for multiple times to the same bean and the same method.
In the logs it shows like this,
Message History
RouteId ProcessorId Processor Elapsed (ms)
[route3 ] [route3 ] [mina2://tcp://localhost:8888?codec=%23hl7codec&sync=true ] [ 29642]
[route3 ] [dynamicRouter1 ] [dynamicRouter[bean{com.eg.service.handlerService, ] [ 29632]
[route1 ] [to1 ] [bean:handlerService?method=handleMessage ] [ 11835]
[route1 ] [to1 ] [bean:handlerService?method=handleMessage ] [ 12776]
[route1 ] [to1 ] [bean:handlerService?method=handleMessage ] [ 4700]
You can observe the route1 is repeated for multiple times. means it is redirecting to the same method for multiple times. Instead i want to send response back to the user. So how can i do that ?
Read the documentation!
http://camel.apache.org/dynamic-router
See that beware box on that page
Also related is this SO with some details: Dynamic routing in camel en-queues messages infinitely

Resources