OData filter objects that contain particular items in subarray - odata

I have the following situation:
I have an object
This object has an item that is an object again
The second object contains array of objects with ids
Can I filter only the parent objects that have subobjects that contain something in particular in the array on the bottom of the tree?

Try this:
$filter=nameOfObjectArrayProperty/any(o: contains(o/id, 'some-alue'))
or
$filter=nameOfObjectArrayProperty/any(o: o/id eq 'some-value')
It's also important to note that "/any" can be replaced with "/all" if you want all the subobjects to match your filter criteria.

Related

ActiveRecord: Querying for parent record where child records have certain values in an AND query

Normally I understand that if you pass an array of values to an ActiveRecord query it executes it like an OR statement. That is to say:
Parent.joins(:kiddos).where(kiddos: {rando_attr:[1,2]})
This query looks for Parent objects where the parent object has a kiddo object that has rando_attr of EITHER 1 OR 2.
In my case however, I want to look for Parent object where the parent object has a kiddo object with rando_attr of 1, AND ALSO has a kiddo object with rando_attr of 2.
How would I write this query?
Parent.joins(:kiddos)
.where(kiddos: {rando_attr:[1,2]})
.group(:id).having('COUNT(DISTINCT(kiddos.rando_attr)) = 2')
Indeed the array syntax makes an IN query (which is like a logical or), an alternative to grouping (#Lam's answer) can be using 2 wheres
Parent.joins(:kiddos).where(kiddos: {rando_attr: 1}).where(kiddos: {rando_attr: 2})

Active Record Array array query - to check records that are present in an array

I have an Objective model which has an attribute called as labels whose values are array data type. I need to query all the Objectives whose labels attribute has values that are present in some particular array.
For Example:
I have an array
a = ["textile", "blazer"]
the Objective.labels may have values as ["textile, "ramen"]
I need to return all objectives that might have either "textile" or "blazer" as one of their labels array values
I tried the following:
Objective.where("labels #> ARRAY[?]::varchar[]", ["textile"])
This returns some records.Now when I try
Objective.where("labels #> ARRAY[?]::varchar[]", ["textile", "Blazer"])
I expect it to return all Objectives which contains at-least one of the labels array value as textile or blazer.
However, it returns an empty array. Any Solutions?
Try && overlap operator.
overlap (have elements in common)
Objective.where("labels && ARRAY[?]::varchar[]", ["textile", "Blazer"])
If you have many rows, a GIN index can speed it up.

Linked List without using pointers and struct

How to implement linked list in C/C++ with out using
struct node{
int data;
struct node *next;
}
just using two arrays, one for data, other for next node
Sure you can. There is some discussion about the topic here: Is a Linked-List implementation without using pointers possible or not?
One implementation would be to create an array, and store the nodes in the array. Wikipedia has a good pseudo-code example: http://en.wikipedia.org/wiki/Linked_list (Linked lists using arrays of nodes section)
You define two arrays
1.Data Array
2.Index Array
every data array will contain data value and corresponding index in Index array will contain next node to be pointed by the value element
you need to keep track of the last value added because it gives the index of Index array where you can add an index of the next value pointed by that value node.
Adding a data value is also easy just add a new value in the data array and
fill the previous element value in Index array by the index of the data value in data element.
Data Array 2,5,3,1,2.
Index Array 1,2,3,4,0 (0 means it is not pointing to any data element)
add element: 2,5,3,1,2,77.
Index Array 1,2,3,4,5,0.
delete element: 2,5,0,1,2,77
Index Array 1,3,0,4,5,0.

Querying array element in node property

I have nodes within a the graph with property pathway storing an array of of values ranging from
path:ko00030
path:ko00010
.
.
path:koXXXXX
As an example, (i'm going to post in the batch import format:https://github.com/jexp/batch-import/tree/20)
ko:string:koid name definition l:label pathway:string_array pathway.name:string_array
ko:K00001 E1.1.1.1, adh alcohol dehydrogenase [EC:1.1.1.1] ko path:ko00010|path:ko00071|path:ko00350|path:ko00625|path:ko00626|path:ko00641|path:ko00830
the subsequent nodes might have a different combination of pathway values.
How do i query using CYPHER to retrieve all nodes with path:ko00010 in pathway
the closest i've gotten is using the solution provided for a different problem:
How to check array property in neo4j?
match (n:ko)--cpd
Where has(n.pathway) and all ( m in n.pathway where m in ["path:ko00010"])
return n,cpd;
but here only nodes with pathways matching exactly to the list provided are returned.
ie. if i were to query path:ko00010 like in the example above, I'll only be able to retrieve nodes holding path:ko00010 as the only element in the pathway property and not nodes containing path:ko00010 as well as other path:koXXXXX
In your query the extension of the predicate ALL is all the values in the property array, meaning that your query will only return those cases where every value in the pathway property array are found in the literal array ["path:ko00010"]. If I understand you right you want the opposite, you want to test that all values in the literal array ["path:ko00010"] are found in the property array pathway. If that's indeed what you want you can just switch their places, your WHERE clause will then be
WHERE HAS(n.pathway) AND ALL (m IN ["path:ko00010"] WHERE m IN n.pathway)
It is not strictly correct to say that your query only matches cases where the array you ask for and the property array are exactly the same. You could have had more than one value in the literal array, something like ["path:ko00010","path:ko00020"], and nodes with only one one of those values in their pathway array would also have matched–as long as all values in the property array could be found in the literal array. Conversely, with the altered WHERE filter that I've suggested, the query will match any node that has all of the values of the literal array in their pathway property.
If you want to filter the matched patterns with an array of values where all of them have to be present, this is good. In your example you only use one value, however, and for those queries there is no reason to use an array and the ALL predicate. You can simply do
WHERE HAS(n.pathway) and "path:ko00010" IN n.pathway
If in some context you want to include results where any of a set of values are found in the pathway property array you can just switch from ALL to ANY
WHERE HAS(n.pathway) AND ANY (m IN ["path:ko00010","path:ko00020"] WHERE m IN n.pathway)
Also, you probably don't need to check for the presence of the pathway property, unless you have some special use for it you should be fine without the HAS(n.pathway).
And once you've got the queries working right, try to switch out literal strings and arrays for parameters!
WHERE {value} IN n.pathway
// or
WHERE ALL (m IN {value_array} WHERE m IN n.pathway)
// or
WHERE ANY (m IN {value_array} WHERE m IN n.pathway)

sorting custom objects from array into dictionary by property

Is there an easy way to sort an array of custom objects (in this case Lists) into a dictionary based on a particular property of each list.
[List1, List2, List3, List4, List5];
For example, each List object has an NSString type property, which can be either "MyList","Sent","Received"
How would I create a dictionary based on these properties so that I have a dictionary like so:
"MyList" -> array of lists with MyList as their type property [List1, List5];
"Sent" -> array of lists with Sent as their type property "Received" [List3;
"Received" -> array of lists with Received as their type property [List2, List4];
I'd really rather not loopthrough my entire array of List objects if possible
You need to iterate the array and build your dictionary. If the key isn't already there, create the array and add it to the dictionary, then add the new item to it.
You could alternately use predicates to filter the array into sub-arrays and build the dictionary like that but it's a similar amount of code (for a few options) and doesn't support automatic future expansion when you have another value for the key you're organising on.

Resources