RestAssured matchers for array of strings not working as expected - rest-assured

When I try to match a list of strings:
public void logHeaders(List<String> headers) {
then().body("headers", Matchers.contains(headers));
}
I get:
JSON path headers don't match.
Expected: iterable containing [<[Depth Top (m), Depth Base (m), Collector No., Sample No., Analysis Type, Age Range, Comments, Method, Sample Type]>]
Actual: [Depth Top (m), Depth Base (m), Collector No., Sample No., Analysis Type, Age Range, Comments, Method, Sample Type]
Now that looks like a match to me. I have tried all sorts of variations and seems to match many questions and articles. What I am doing wrong?
JSON looks like:
{
"id": 14900,
"headers": [
"Depth Top (m)",
"Depth Base (m)",
"Collector No.",
"Sample No.",
"Analysis Type",
"Age Range",
"Comments",
"Method",
"Sample Type"
], etc

Arrgh! Comparing lists to strings. Needs to be:
then().body("headers", Matchers.contains(headers.toArray(new String[headers.size()])));

Related

How to do grouping in elasticsearch with searchkick rails

I have articles data indexed to elastic as follows.
{
"id": 1011,
"title": "abcd",
"author": "author1"
"status": "published"
}
Now I wanted to get all the article id grouped by status.
Result should someway look like this
{
"published": [1011, 1012, ....],
"draft": [2011],
"deleted": [3011]
}
NB: I tried normal aggs (Article.search('*',aggs: [:status], load: false).aggs) , it just giving me the count of each items in, I want ids in each item instead
#Crazy Cat
You can transform you query in this way:
sort(Inc/Dec order) your response from ES over field "status".
Only Ask ES query to return only ID Field and status.
Now the usage of sorting would be it would sort your response to like this: [1st N results of "deleted" status, then N+1 to M results to "draft" and then M+1 to K results to "published"].
Now the advantages of this technique:
You will get flagged ids field of every document over which you can apply operations in you application.
Your query would be light weight as compared to Aggs query.
This way you would also get the metdata of every document ike docId of that document.
Now the Disadvantages:
You would always have to give a high upper bound of your page size, but You can also play around with count coming in the metadata.
Might take a bit more of network size as it returns redundant status in every document.
I Hope this redesign of your query might be helpful to you.

Is there a way to dynamically generate nodes from JSON with apoc.load.json procedure?

I would like to create a set of nodes and relationships from a JSON document. Here is sample JSON:
{"records": [{
"type": "bundle",
"id": "bundle--1",
"objects": [
{
"type": "evaluation",
"id": "evaluation--12345",
"name": "Eval 1",
"goals": [
"test"
]
},
{
"type": "subject",
"id": "subject--67890",
"name": "Eval 2",
"goals": [
"execute"
]
},
{
"type": "relationship",
"id": "relationship--45678",
"relationship_type": "participated-in",
"source_ref": "subject--67890",
"target_ref": "evaluation--12345"
}
}]
}
And I would like that JSON to be represented in Neo similar to the following:
(:evaluation {properties})<-[:RELATIONSHIP]-(:subject {properties})
Ultimately I would like to have a model that represents the evaluation, subject, and relationship generated via a few cypher calls with as little outside manipulation as possible. Is it possible to use the apoc.create.* set of calls to create the necessary nodes and relationships from this JSON? I have tried something similar to the following to get this JSON to load and I can get it to create nodes of an arbitrary, in this case "object", type.
WITH "file:///C:/path/to/my/sample.json" AS json
CALL apoc.load.json(json, "$.records") YIELD value
UNWIND value.objects as object
MERGE (o:object {id: object.id, type: object.type, name: object.name})
RETURN count(*)
I have tried changing the JSONPath expression to filter different record types but it is difficult to run a Goessner path like $.records..objects[?(#.type = 'subject')] thanks to the embedded quotes. This would also lead to multiple runs (I have 15 or so different types) against the real JSON, which could be very time consuming. The LoadJSON docs have a simple filter expression and there is a blog post that shows how to parse stackoverflow but the JSON objects are keyed in a way that is easy to map in cypher. Is there a cypher trick or APOC I should be aware of that can help me solve this problem?
I would approach this as a two-pass method:
First pass: create the nodes for evaluation and subject. You could use apoc.do.case/when if helpful
Second pass: only scan for relationship and then do a MATCH to find the evaluation and subject nodes based on the source_ref and target_ref, and then MERGE or CREATE the relationship to connect them.
Like this you're not impacted by situations such as the relationship coming before the nodes it connects etc. or how many items you've got within objects
As Lju pointed out, the apoc.do.case function can be used to create a set of conditions to check, followed by a cypher statement. Combining that with another apoc call requires the returns from each apoc call to be handled properly. My answer ended up looking like the following:
WITH "file:///C:/path/to/my/sample.json" AS json
CALL apoc.load.json(json, "$.records") YIELD value as records
UNWIND records.objects as object
CALL apoc.do.case(
[object.type="evaluation", "MERGE (:Evaluation {id: object.id}) ON CREATE SET Evaluation.id = object.id, Evaluation.prop1 = object.prop1",
object.type="subject", "MERGE (:Subject {id: object.id}) ON CREATE SET Subject.id = object.id, Subject.prop1 = object.prop1",
....]
"<default case cypher query goes here>", {object:object}
)
YIELD value RETURN count(*)
Notice there are two apoc calls that YIELD. Use aliases to help the parser differentiate between objects. The documentation for the apoc.do.case is a little sparse but describes the syntax for the statement. It looks like there are other ways to accomplish this task but with smaller JSON files, and a handful of cases, this works well enough.

Graph "beta" filtering for date time from audit logs not working (returns all data)

Using the graph explorer, I'm trying to limit (time box) the number of entries being returned. This is so I can extract the data from Azure to upload into our SIEM portal. I am getting the data back (10's of thousands of datapoints) - but I need to time box them.
This works as a query (both in graph explorer and from powershell) - but the results are not in the time frame requested. I've tried different time formats (including down to the second) and they don't limit the results.
It seems like it isn't going deeper into the data structure for the filter to operate on.
Any suggestions on the filter or a different approach (without accepting all the data each query and doing a post-results filter)?
Note: I also tried the activityDateTime prefix with value/ and value\ (reading from a different article I found) - so value/activityDateTime and value\activityDateTime - no different results (no errors either)
This is the 'get' from graph explorer (beta selected)
https://graph.microsoft.com/beta/auditLogs/directoryAudits?=activityDateTime ge 2018-07-16T15:48:00 and activityDateTime lt 2018-07-16T15:58:00
returned this (only partially results, guid/hex strings were removed) - you'll notice that the activityDateTime returned below is not >= and < the date/time passed in the query
{
"#odata.context": "https://graph.microsoft.com/beta/$metadata#auditLogs/directoryAudits",
"#odata.nextLink": "https://graph.microsoft.com/beta/auditLogs/directoryAudits?=value%2factivityDateTime+ge+2018-07-16T15%3a48%3a00+and+value%2factivityDateTime+lt+2018-07-16T15%3a58%3a00&$skiptoken=[hex string removed]_1000",
"value": [
{
"id": "Directory_[hex string removed]",
"category": "Core Directory",
"correlationId": "[GUID removed]",
"result": "success",
"resultReason": "",
"activityDisplayName": "Update group",
**"activityDateTime": "2018-07-18T14:30:44.6046176Z"**,
"loggedByService": "AzureAD",
"initiatedBy": {
"user": null,
"app": null
},
"targetResources": [
{
"#odata.type": "#microsoft.graph.targetResourceGroup",
[rest of data returned 1000 total removed]
You need to specify the parameter name. Otherwise, the API has no way of knowing what operation you want (select, orderby, filter). In this case, you want to $filter like this: $filter=activityDateTime ge 2018-07-16T15:48:00Z and activityDateTime lt 2018-07-16T15:58:00Z.
https://graph.microsoft.com/beta/auditLogs/directoryAudits?$filter=activityDateTime ge 2018-07-16T15:48:00Z and activityDateTime lt 2018-07-16T15:58:00Z

Cypher Query Language/Neo4j - Nested Returns of Variable Path Length

I have a graph structure in Neo4j for a questionnaire that has the following relationships:
(a:Category)-[:INITIAL_QUESTION]->(b:Question)-[c:Answer*]->(d:Question)
where the specific question text is contained in (b|d).text and the possible answers for each question is contained in the relationship c.response
From the initial question, there are some paths that are longer than others. I would like the return to look something like this:
{"category": "example questionnaire category",
"initialQuestion" : {
"id": 1,
"text": "Example text here",
"possibleAns": {
"yes" : {
"id": 2,
"text": "Second question text here?",
"possibleAns": {
"ans1": {/*Question 4 containing all possible child question nodes nested
in possibleAns*/},
"ans2": {/*Question 5 containing all possible child question nodes nested
in possibleAns*/},
}
},
"no" :{
"id": 3,
"text": "Different question text here?",
"possibleAns": {
"ans1": {/*Question 6 containing all possible child question nodes nested
in possibleAns*/},
"ans2": {/*Question 7 containing all possible child question nodes nested
in possibleAns*/},
}
}
}
}
}
so that the entire category questionnaire is contained in a single, nested map. I've seen some other examples, but haven't been able to tweak those queries to fit my needs, especially given the variable depth of the questionnaire branches.
Is there a Cypher query that makes this possible? If not, what would be the best approach for retrieving the entire questionnaire from the db?
I think that this is not done with standard tools (cypher etc.)
So, or transform the result from cypher query in the json-tree programmatically.
Or, if your neo4j-server versions not less 3.0, you can try apoc.convert.toTree:
MATCH path = (a:Category)
-[:INITIAL_QUESTION]->(b:Question)-[c:Answer*]->
(d:Question)
WITH collect(path) as paths
CALL apoc.convert.toTree(paths) yield value as tree
RETURN tree

freebase get buildings and geolocation

I need to get all the buildings with "church" function that are far 100km from a specified point (lat, lng). I made in this way:
[{
"id": null,
"name": null,
"type": "/architecture/building",
"building_function" : [{"name" : 'church'}],
"/location/location/geolocation" : {"latitude" : 45.1603653, "longitude" : 10.7976976}
"/location/location/area" : 100
}]​
but I alway get an empty response
code: "/api/status/ok"
result: []
status: "200 OK"
transaction_id: "cache;cache03.p01.sjc1:8101;2011-04-16T12:32:45Z;0035"
What am I missing?
Thanks
An area isn't a distance and you probably don't want an exact match to the value "100" anyway. You've asked for things which are precisely at that long/lat and have exactly that area.
Are you looking for churches which are less than a certain distance, more than a certain distance, or exactly the given distance? You probably want to look at the Geosearch API http://api.freebase.com/api/service/geosearch?help (although it's not a long term solution since it's been deprecated)
The /location/location/area property is used to query locations which cover a certain amount of area. So your query looks for buildings centered at (45.1603653, 10.7976976) which cover an area of 100km. Naturally there are no results that match.
Searching for topics within 100km of a those coordinates takes a little more work. You'll need to use the Geosearch service which is still in alpha. The following query should give you the results that you're looking for:
http://www.freebase.com/api/service/geosearch?location={%22type%22:%22Point%22,%22coordinates%22:[10.7976976,45.1603653]}&type=/architecture/building&within=100&indent=1
Once you have that list of buildings, you can query the MQL Read API to find out which ones are churches like this:
[{
"id": null,
"name": null,
"type": "/architecture/building",
"building_function" : [{"name" : 'church'}],
"filter:id|=":[
"/en/verona_arena",
"/en/basilica_palladiana",
"/en/teatro_olimpico",
"/en/palazzo_del_te",
"/en/villa_capra_la_rotonda",
"/en/villa_badoer",
"/en/san_petronio_basilica",
"/en/palazzo_schifanoia",
"/en/palazzo_chiericati",
"/en/basilica_di_santandrea_di_mantova",
"/en/basilica_of_san_domenico",
"/en/castello_estense",
"/en/palazzo_dei_diamanti",
"/en/villa_verdi",
"/en/cathedral_of_cremona",
"/en/monte_berico",
"/en/villa_pojana",
"/en/san_sebastiano",
"/en/cremona_baptistery",
"/en/palazzo_della_pilotta"
]
}]​
Right now its only matching 2 results so you'll probably need to edit some of those topics to mark them as churches.

Resources