I'm trying to find the shortest path along with relations on the nodes on the path, for which below query is used.
MATCH p = shortestPath((p1:Person { name: 'Kevin Bacon' })-[*..15]-
(p2:Person { name: 'Meg Ryan' }))
UNWIND nodes(p) as n
MATCH (n)-[*]->(q)
RETURN n, q
However i want to return the result as json object with data format as below in c#. I understand we have to use apoc. However can't really understand how to proceed.
{
"results": [
{
"data": [
{
"graph": {
"nodes": [
{
"id": "1",
"labels": ["James"],
"properties": {
"ShortName": "jammy",
"Type": "Person",
"Age": 34
}
},
{
"id": "2",
"labels": ["Brad"],
"properties": {
"name": "Brad",
"PlaceOfBirth": "California",
"Type": "Person",
"description": "Nice actor",
}
},
{
"id": "3",
"labels": ["Titanic"],
"properties": {
"movieName": "Titanic",
"Type": "Movie",
"description": "Tragedy",
}
}
],
"relationships": [
{
"id": "4",
"type": "ACTED_IN",
"startNode": "1",
"endNode": "3",
"properties": {
"from": 1470002400000
}
}
]
}
}
]
}
],
"errors": []
}
You can collect the nodes and relationships separately and add it on the result.
MATCH p = shortestPath((p1:Person { name: 'Kevin Bacon' })-[*..15]-(p2:Person { name: 'Meg Ryan' }))
UNWIND nodes(p) as n
MATCH (n)-[r]->(q)
WITH collect(distinct n) + collect(distinct q) as node_list, collect(distinct r) as rel_list
RETURN {results: {data: {graph: {nodes: node_list, relationships: rel_list}}, error: []}} as output
I wanted the first level incoming and outgoing relations of all the nodes on the path. Slighty modified the answer for anyone looking for something similar in future. Thanks Jose.
MATCH p = shortestpath((p1:Person { name: 'Kevin Bacon' })-[*..30]-
(p2:Person { name: 'Meg Ryan' }))
UNWIND nodes(p) as n
MATCH (n)<-[r*1]->(q)
WITH collect(distinct n) + collect(distinct q) as node_list,
collect(distinct r) as rel_list
RETURN {results: {data: {graph: {nodes: node_list, relationships:
rel_list}}, error: []}} as output
Related
I have a json with below structure.
{
"root": {
"students": [
{
"student": {
"Id": "1",
"Name": "abc"
},
"Type": "Update",
"Time": "20220520050003Z"
},
{
"student": {
"Id": "2",
"Name": "def"
},
"Type": "Update",
"Time": "20220520050009Z"
},
{
"student": {
"Id": "3",
"Name": "ghi"
},
"Type": "Create",
"Time": "20220520050021Z"
},
{
"student": {
"Id": "1",
"Name": "abc"
},
"Type": "Create",
"Time": "20220520050024Z"
}
]
}
}
I want to read the students json array and group them which has same Id under student object
For example Id 1 has two entries
{
"student": {
"Id": "1",
"Name": "abc"
},
"Type": "Update",
"Time": "20220520050003Z"
}
and
{
"student": {
"Id": "1",
"Name": "abc"
},
"Type": "Create",
"eventTime": "20220520050024Z"
}
So I want to group them based on same id and get a list of objects which has record for each unique Id.
I tried with newtonsoft linq , but not able to group them with Id value. I want to know how i can group them
JObject obj = JObject.Parse(jsonasstring);
JObject objRoot = (JObject)obj.SelectToken("root");
var studentsList = from students in objRoot["students"]
select students["student"];
On your example you have different property names("Time", "eventTime") - I assumed that "Time" is a correct one.
Below you can see how grouping was done:
JObject obj = JObject.Parse(jsonasstring);
JObject objRoot = (JObject)obj.SelectToken("root");
var studentsList = from students in objRoot["students"]
group students by students["student"]["Id"] into studentsgroup
select new { StudentId = studentsgroup.Key, Students = studentsgroup.Select(x => new {StudentName = x["student"]["Name"], Type = x["Type"], Time = x["Time"]})};
You get students list, group it by studentId and do selection as you need.
Result:
Select all objects in the students JSON array, then use Linq's GroupBy to bucket them by the student.Id property.
var studentsGroupedById = JObject.Parse(jsonasstring)
.SelectTokens("$.root.students[*]")
.GroupBy(x => x["student"]["Id"]);
In each group, Key is the student.Id property, and you can enumerate through all the entries in the group (the inner foreach loop).
Runnable online version that prints out results to demonstrate the groups
I corrected what I hope is a typo in your JSON - the first student entry has a Time property, not an eventTime property. If that's actually how the data is formatted you'll need to account for it.
I have a problem about querying a complex data type with c# nest api in elasticsearch. My model in elasticsearch is like this:
"hits": [
{
"_index": "post",
"_type": "postmodel",
"_source": {
"projectId": "2",
"language": "en",
"postDate": "2017-06-11T08:39:32Z",
"profiles": [
{
"label": "Emotional",
"confidence": 1
}
]
}
},
{
"_index": "post",
"_type": "postmodel",
"_source": {
"projectId": "3",
"language": "en",
"postDate": "2017-06-11T08:05:01Z",
"profiles": [
{
"label": "Fact oriented",
"confidence": 0.69
},
{
"label": "Rational",
"confidence": 1
}
]
}
},
...
By using c# Nest API, i want to fetch the postmodels which is projectId=3 and with "Rational" profile. My current code looks like this:
var postModels = await _elasticClient.SearchAsync<PostModel>(s => s
.Index("post")
.Query(q =>
{
QueryContainer query = new QueryContainer();
query = query && q.Match(m => m.Field(f => f.ProjectId)
.Query("3"));
return query;
}));
But i dont know how to query "Profiles". i want to extend my query to fetch specific profiles as well. I would be happy if someone can help me with this problem. Thank you in advance.
I am fairly new to ElasticSearch and am having issues getting search results that I perceive to be good. My objective is to be able to search an index of medications (6 fields) against a phrase that the user enters. It could be one ore more words. I've tried a few approaches, but I'll outline the best one I've found so far below. Let me know what I'm doing wrong. I'm guessing that I'm missing something fundamental.
Here is a subset of the fields that I'm working with
...
"hits": [
{
"_index": "indexus2",
"_type": "Medication",
"_id": "17471",
"_score": 8.829264,
"_source": {
"SearchContents": " chew chewable oral po tylenol",
"MedShortDesc": "Tylenol PO Chew",
"MedLongDesc": "Tylenol Oral Chewable"
"GenericDesc": "ACETAMINOPHEN ORAL"
...
}
}
...
The fields that I'm searching against used an Edge NGram Analyzer. I'm using the C# Nest library for the indexing
settings.Analysis.Tokenizers.Add("edgeNGram", new EdgeNGramTokenizer()
{
MaxGram = 50,
MinGram = 2,
TokenChars = new List<string>() { "letter", "digit" }
});
settings.Analysis.Analyzers.Add("edgeNGramAnalyzer", new CustomAnalyzer()
{
Filter = new string[] { "lowercase" },
Tokenizer = "edgeNGram"
});
I am using a more_like_this query against the fields in question
GET indexus2/Medication/_search
{
"query": {
"more_like_this" : {
"fields" : ["MedShortDesc",
"MedLongDesc",
"GenericDesc",
"SearchContents"],
"like_text" : "vicodin",
"min_term_freq" : 1,
"max_query_terms" : 25,
"min_word_len": 2
}
}
}
The problem is that for this search for 'vicodin', I'd expect to see matches with the full work first, but I don't. Here is a subset of the results from this query. Vicodin doesn't show up until the 7th result
"hits": [
{
"_index": "indexus2",
"_type": "Medication",
"_id": "31192",
"_score": 4.567309,
"_source": {
"SearchContents": " oral po victrelis",
"MedShortDesc": "Victrelis PO",
"MedLongDesc": "Victrelis Oral",
"RepresentativeRoutedGenericDesc": "BOCEPREVIR ORAL",
...
}
}
<5 more similar results>
{
"_index": "indexus2",
"_type": "Medication",
"_id": "26198",
"_score": 2.2836545,
"_source": {
"SearchContents": " (original 5 500 feeding mg strength) tube via vicodin",
"MedShortDesc": "Vicodin 5 mg-500 mg (Original Strength) via feeding tube",
"MedLongDesc": "Vicodin 5 mg-500 mg (Original Strength) via feeding tube",
"GenericDesc": "HYDROCODONE BITARTRATE/ACETAMINOPHEN ORAL",
...
}
}
Field Mappings
"OrderableMedLongDesc": {
"type": "string",
"analyzer": "edgeNGramAnalyzer"
},
"OrderableMedShortDesc": {
"type": "string",
"analyzer": "edgeNGramAnalyzer"
},
"RepresentativeRoutedGenericDesc": {
"type": "string",
"analyzer": "edgeNGramAnalyzer"
},
"SearchContents": {
"type": "string",
"analyzer": "edgeNGramAnalyzer"
},
Here is what ES shows for my _settings for analyzers
"analyzer": {
"edgeNGramAnalyzer": {
"type": "custom",
"filter": [
"lowercase"
],
"tokenizer": "edgeNGram"
}
},
"tokenizer": {
"edgeNGram": {
"min_gram": "2",
"type": "edgeNGram",
"max_gram": "50"
}
}
As per the above mapping edgeNGramAnalyzer is the search-analyzer for the fields as a result the search query would also get "edge ngrammed". You probably do not want this .
Change the mapping to set only the index_analyzer option as edgeNgramAnalyzer.
The search_analyzer would then default to standard.
Example:
"SearchContents": {
"type": "string",
"index_analyzer": "edgeNGramAnalyzer"
},
I have an object that I am converting to JSON to be consumed by Ember.js.
Currently I have some child objects that are fully expanded but ember expects
just an array of ids on the client side. How can I flatten the object out to
be a int[]
items = Mapper.Map<IList<Item>>(client.GetItems());
foreach (var item in items)
{
int[] choices = item.Choices.Select(x => x.Id).ToArray();
item.Choices = choices;
}
get an error about not being able to convert to type int[] from IList<Item>
how can I cast the property?
example current JSON I produce after serializing
{ "items": [
{
"id": 0,
"name": "Item0",
"description": "...",
"choices": [
{ "id": 0, "property": "somevalue" },
{ "id": 1, "property": "somevalue" },
]
},
{
"id": 1,
"name": "Item1",
"description": "...",
"choices": [
{ "id": 0, "property": "somevalue" },
{ "id": 1, "property": "somevalue" },
]
}
]}
The JSON I would like to produce
{ "items": [
{
"id": 0,
"name": "Item0",
"description": "...",
"choices": [0, 1]
},
{
"id": 1,
"name": "Item1",
"description": "...",
"choices": [0, 1]
}
]}
SelectMany flattens List of Lists and produces single List with all items.
items.SelectMany(x=>x.Choices.Select(y=>y.Id).ToArray()));
get an error about not being able to convert to type int[] from IList how can I cast the property?
You cannot cast one type to another. Instead you can create another property of type int[] in your class and use the LINQ statement in getter (with necessary validation checks).
public int[] ChoiceIDs
{
get {
return this.Choices.Select(x => x.Id).ToArray();
}
}
I am looking for a good way to feed a d3.js bubble chart with data from my MVC application. For example the standard bubble chart expects nested data in the form:
{
"name": "flare",
"children": [
{
"name": "analytics",
"children": [
{
"name": "cluster",
"children": [
{
"name": "CNN",
"size": 3938
}
]
},
{
"name": "graph",
"children": [
{
"name": "MTV",
"size": 3534
}
]
}
]
}
]
}
What I have on the server side is this linq query to a SQL database:
var results = from a in db.Durations
where a.Category == "watch"
group a by a.Description
into g
select new
{
name = g.Key,
size = g.Select(d => new{d.Begin, d.End}).Sum(d => SqlFunctions.DateDiff("hh", d.Begin, d.End))
};
return Json(results, JsonRequestBehavior.AllowGet);
The query result, parsed as Json, looks like this:
[{"name":"CNN","size":1950},{"name":"MTV","size":1680}]
I've got stuck in the head on what would be a good way to achieve the correct formatting and to create the nested structure from my query results..
server-side, using anonymous types
server-side, adjusting the linq-query
client-side, using d3.js nest
use a simpler bubble model since for my purpose, the nested
structure with children is not really needed
something totally different and much much cooler than 1-4
Thank you for any input.
Replace your return statement with the following one.
return Json(new
{
name = "Sites",
children = results
},
JsonRequestBehavior.AllowGet);
That will give you the following:
{
"name": "Sites",
"children": [
{
"name": "CNN",
"size": 1950
},
{
"name": "MTV",
"size": 1680
}
]
}
To serve as an example, suppose each website had an additional string Type property, with values such as "News" or "Music". Then you could do the following.
return Json(new
{
name = "Sites",
children = results.GroupBy(site => site.Type).Select(group => new
{
name = group.Key,
children = group
}
},
JsonRequestBehavior.AllowGet);
This would give you something like the following.
{
"name": "Sites",
"children": [
{
"name": "News",
"children": [
{
"name": "CNN",
"size": 1950
},
{
"name": "The Verge",
"size": 1600
}
]
},
{
"name": "Music",
"children": [
{
"name": "MTV",
"size": 1680
},
{
"name": "Pandora",
"size": 2000
}
]
}
]
}