I'm trying to parse an HTML document into nested set of tags and content. It needs to support arbitrary nesting depth. The object (created in
Python code) looks like:
{
"content": [
"some text about a thing, ",
{"content": "More text with additional set of tags ",
"tags": ["strong"]
}
],
"tags": ["p"]
}
ES seems to dislike this structure, because the content field is of both a text and object type, producing this error; "reason": "mapper [content] of different type, current_type [text], merged_type [ObjectMapper]"
Does anyone have any ideas on how to index this type of object, and also allow for searches on both tags and content? Ideally I'd like to search by tags associated with the ancestors of a given object too. I can reformat it to
{
"content": [
{"content": "some text about a thing, "},
{"content": "More text with a different set of tags ",
"tags": ["strong"]
}
],
"tags": ["p"]
}
But then searching isn't very effective as I need to write content.content:"search string" to get results, which will become hard with multiple levels of nesting.
Why not store the ancestor tags in a separate field? Implementing a nested set will should solve your problem too.
Edit: As requested here comes a example of a nested set
Imagine a tree structure. Every node in this tree has a set of properties like description, or other attributes. Each node holds also a reference to it's parent node. Beside this there are two numbers: left and right position in the tree when traversing with in-depth search:
A(parent:null, left:1, right:12, desc:“root node“)
B(parent:A, left:2, right:3, desc:“left child“)
C(parent:A, left:4, right:11, desc:“right child“)
D(parent:C, left:5, right:6, desc:“foo“)
E(parent:C, left:7, right:10, desc:“bar“)
F(parent:E, left:8, right:9, desc:“baz“)
Calculating all ancenstors of a node is now easy:
ancestors(F for X) = search nodes as N WHERE N.left < X.left AND N.right > X.right
For the node F you'll get [E,C,A]. Ordering them by the left value you'll get the proper order for the ancestors of F.
So now you can use this criteria for the filter query in ES and use a second query for the search in the attributes of filtered nodes.
This structure is very efficient when looking for subtrees, but has downsides when you change the node order/position.
If you need further explanation, please add a comment.
Related
I would like to perform a depth first search on my graph and so, get all the paths existing from a given node ('N1456' in my example), and all the nodes of theses path must have the same property "PROPERTY_TO_FILTER".
Typically, my graph is composed of two types of node, and two types of relations.
For now, I tested the following request :
WITH "
MATCH (my_node{name : 'N1456'})
CALL apoc.path.expandConfig(protein, {uniqueness:'NODE_GLOBAL', bfs : FALSE}) YIELD path
WITH path, my_node, last(nodes(path)) as subgraph
WHERE my_node<> subgraph and my_node.my_property CONTAINS 'PROPERTY_TO_FILTER'
RETURN nodes(path), length(path) AS len
ORDER BY len DESC" AS query
CALL apoc.export.json.query(query, "my_results.json", {})
YIELD properties, data
RETURN properties, data;
However, the results are not the ones attended. I get a list of paths but only the first node has the property "PROPERTY_TO_FILTER" ; this filter is not taken into account for the other nodes...
I guess I should put a filter at apoc.path.expandConfig level, but I see in the documentation that this is only possible to filter the node label, not the node properties.
Could someone help please ?
Maybe this can help:
MATCH(fromNode:LABEL{name : 'N1456'})-[r:REL_TO_TRAVERSE*1..2]->(toNode:LABEL)
WHERE toNode.my_property CONTAINS 'PROPERTY_TO_FILTER'
RETURN fromNode,r,toNode
It's called variable length pattern matching:
https://neo4j.com/docs/cypher-manual/current/syntax/patterns/#cypher-pattern-varlength
I am trying to get max & sum of two columns in a filter expression using MapboxGL-js. The two columns of interest may contain nulls.
Tried this for addition and it does not work (nothing shows up on the map)
["+",["to-number",['get', "col1"]],["to-number",['get', "col2"]]]
For max,I tried this and does not work either.
["max",["to-number",['get', "col1"]],["to-number",['get', "col2"]]]
Any suggestions? Thanks!
The filter defined in mapboxgl-js is
filter is a property at the layer level that determines which features should be rendered in a style layer.
In official mapboxgl-js example you can see that in case condition is true the feature will be rendered:
"filter": ["==", "icon", symbol]
where "icon" is equal to symbol (a variable that is set to the selected feature's icon property).
In your example there are no conditional operation done.
In case you are trying to show the "sum" or "max" as a layer's "text-field", you should use it there and not in filter, and return string after completing your Math operations.
so it will be
"test-field": ["to-string", ["max",["to-number", ["get", "col1"]],["to-number", ["get", "col2"] ]]],
Link to Filter Doc
Link to Expressions Docs
Hope this helps
What is the proper way to achieve the visual equivalent of this:
, but for an array that is part of the entity of the Resource itself (as opposed being a field on a referenced entity)? For instance, if my document looked like {"id": 1, "title": "my title", "comments_by": ["john", "kate"]}.
I tried to nest a List element but wasn't able to make it look right.
You're on the right track; This should achieve your goal:
<FunctionField render={record=>
record.comments_by.map((by,index)=> <ChipField record={{by}} source="by"/>)
}/>
Is it possible to search an account's custom data to find a value contained in an array?
Something like:
?customData.[arrayName].{key}=value
The Stormpath docs don't mention array searching.
Yes, with Stormpath it is totally possible to search for custom data even if the values are stored as an array!
Please note that the field names are simple names, and the values are what are different data types like array, map, string etc... so the query is not as complex as one would think :-)
For example, if I want to store custom data called favoriteColors, which is an array like
"favoriteColors": [ "red", "black", "blue", "white" ]
Notice the field name is just like any other field name. The value is the array.
To search for accounts which have a value red in the favoriteColors array, you just need the normal query syntax:
?customData.favoriteColors=red
The full request (if searching a Directory of accounts), might look like this:
https://api.stormpath.com/v1/directories/<directory_uid>/accounts?customData.favoriteColors=red
You could also do the same search on the Tenant resource to search tenant-wide (across all accounts):
https://api.stormpath.com/v1/tenants/<tenant_uid>/accounts?customData.favoriteColors=red
This query would match an account that contains red in the favoriteColors array. If I changed the query to ?customData.favoriteColors=yellow it would not match unless yellow was also added to the array.
Searching for custom data in an array can definitely be done. The syntax is: customData.{fieldName}\[{index}\]=value where {index} can be the specific index you are looking for, or * if you want to find it anywhere in the array. (Note that the [] characters are escaped with a backslash or the query interpreter gets it confused with a range query.)
If you leave off the index entirely, then \[*\] is implied. More precisely, Stormpath will check for either the value in the fieldName or the value as an element in an array of fieldName. However, syntactic sugar can only work if the array field is the last element in your search. Since you can put literally any JSON object into your custom data, Stormpath cannot check every single possibility. Imagine something like customData.foo.bar.baz.qux=bingo. Stormpath would not try to guess that maybe foo is an array, maybe bar is an array or not, maybe baz is an array or not - only maybe qux is an array or not. So, if you want to search an array of objects, you cannot leave out the \[*\].
Here is an example. I have an account with the custom data:
{
"favoriteThings": [
{
"thing": "raindrops",
"location": "on roses"
},
{
"thing": "whiskers",
"location": "on kittens"
},
{
"thing": "snowflakes",
"location": "on my nose and eye lashes"
}
],
"favoriteColors": [
"blue",
"grey"
]
}
The following queries will yield the following results:
customData.favoriteColors=blue will include this account.
customData.favoriteColors\[1\]=blue will not include this account because blue is not at index 1.
customData.favoriteThings\[*\].thing=whiskers will include this account
customData.favoriteThings\[*\].thing=ponies will not include this account because it does not list ponies as one of his favorite things, but may include other accounts with custom data in the same structure.
customData.favoriteThings.thing=whiskers would not include this account or any other accounts with the same custom data structure because in that case, Stormpath would be looking for a single nested JSON favoriteThings object, not an array.
I am starting with D3 and having the following problem:
I've created a directional force layout binding JSON data for links and nodes where data links are:
{
{ "source":"s1" , "target":"t1", "type_link"= "type1"},
{ "source":"s2" , "target":"t2", "type_link"= "type2"}
...
}
...where "source" and "target" identify nodes on both sides of each link.
I need to bind and visualize additional data to each node of previous force layout (no need to add or remove nodes to the layout). New data would be loaded for each existent node from another JSON file:
{
{ "node_id": "s1", value: {JSON object} //with additional data for node "s1"},
{ "node_id": "t1", value: {JSON object} //with additional data for node "t1"}
...
}
So, I would like to append 'value' field data (so, JSON object) to each 'node_id' node.
I thought that I could do it by binding to each node a dataset ( the JSON object), and then appending to each node (not circle) many SVG text as data in JSON object (maybe using .
But I've read in https://github.com/mbostock/d3/wiki/Force-Layout that "a given force layout instance can only be used with a single dataset", so I'm confused.
Please, could you hep me with this issue?
The single dataset means that you can't use a given instance of the force layout with different pairs of nodes and links, because the force layout will store additional properties in the nodes and links. For instance, if you have nodes1, links1 and nodes2, links2, you must create also a force layout for each (nodes, links) pair force1 and force2.
An example of force layout can be found here: http://bl.ocks.org/mbostock/4062045