Is there a way to query google datastore like the CONTAINS filter in GQL? - google-cloud-datastore

Suppose you have 2 entities of same kind which has a List field
The List field in both entities are like:
First entity has elements such as "a" and "b"
Second entity has only one element "a",
so "a" is common for both entities
When querying i want the second entity alone, is there a way to achieve it?

Yes. If it in an array.
Suppose your json is like this
const v1 = {id: 1, list: ['c', 'a', 'd']})
const v2 = {id: 2, list: ['a','s', 'e']})
if you query for list='a', datastore will return both elements.

Related

How to return a node that's the same name as another node but of a specific label? Neo4J

I'm working with financial data, and I want to find a name match between a name that's a synonym of a line item, and another node that has the same name as that synonym but is in a separate node unrelated to the synonym graph and has a specified attribute type that needs to be defined.
Here is some data:
CREATE (n:Test1 {name: "x"})-[r:syn_of]->(s:Test2 {name: "y"})
CREATE (n:Test3 {value: "x"})
So Test3 has the same value stored in attribute format as Test1, but the attribute label is different. How can I return the 'x' from the value attribute of Test3, by querying using Test1 and/or Test2? I know this is a strange problem and due to confidentiality reasons I can't specify why I'm doing this but if anyone could be any help this would be paramount. Thanks in advance.
You can use EXISTS. It will check if there is a connection between Test1 and Test2 before returning the value of Test3. Then you can have a condition on your query that says Test3.value = 'x'. Depending on your input value, your query will look like below;
Given Test1.name ='x' and Test2.name = 'y'
MATCH (n:Test3 {value: 'x'})
WHERE EXISTS ( (:Test1 {name: "x"})-[:syn_of]->(:Test2 {name: "y"}) )
RETURN n
Using WITH clause, you have a variable nameTest1 and assign this to Test3.value
Given Test2.name = 'y'
MATCH (n:Test1)-[:syn_of]->(:Test2 {name: "y"})
WITH n.name as nameTest1
MATCH (n3:Test3 {value: nameTest1 })
RETURN n3

Cosmos DB SQL on nested array without property name

Assume documents of the following schema
{
"id": 1,
"children":[
{"id": "a", "name":"al"},
{"id": "b", "name":"bob"}
]
}
I want to return an array of arrays of all children but filtered on the id property at the root level. Below are the most the known alternatives and limitations:
SELECT * FROM c.children
The above SQL, provides the array of arrays in the right shape but it doens't allow me to filter at the ID in the ROOT level of the document.
SELECT children FROM c WHERE c.id >= 1
The above allows the filtering but returns an array of objects all with the "children" property containing the array.
SELECT child.id, child.name FROM c JOIN child in c.children WHERE c.id >= 1
The above allows the filtering but returns an array of objects. Unlike the previous example the objects are flattened to the child level e.g. property named prefix of "children" is not present.
Again the ordering and grouping children in the returned arrays returned are important on the client side, thus the desired to return all children of a parent grouped in to an array. The first query accomplishes that be doesn't allow filtering.
Please try this SQL:
SELECT value c.children FROM c WHERE c.id >= 1
Result:
[
[
{
"id": "a",
"name": "al"
},
{
"id": "b",
"name": "bob"
}
]
]

Azure Cosmos DB Query: How to concatenate arrays across docs?

Documents in my CosmosDB database all have an array element like so:
{
id: 1,
list: [1, 2, 3]
},
{
id: 2,
list: [2, 3, 4]
},
...
I want a query that concatenates the array "list" across all documents (ideally, I'd like a UNIQUE concatenation but I can start with all of them).
The result I want is:
[1, 2, 3, 2, 3, 4]
or even better:
[1, 2, 3, 4]
This "feels" like an aggregate but I can't seem to get my head around it. Any ideas?
I know I can load each document in turn and iterate. I was hoping to do this with a query and avoid the expense of loading every document in turn.
Using SQL query
You can select individual values from within array by joining and merge the resulting values back into single array by using the value keyword:
SELECT value i
FROM c
join i in c.list
Note that this returns all values in a single array but unfortunately including duplicates.
To my knowledge there is currently no server-side distinct capability. But there is a request of "Provide support for DISTINCT" with 1k+ votes, so I believe it will be possible at some point in the future. If this is something you care about, then go and upvote.
Using SP
Alternative way of getting unique list made on server-side would be to use Stored Procedures within you documentDB collection:
function GetUniqueItems() {
var collection = getContext().getCollection();
var isAccepted = collection.queryDocuments(
collection.getSelfLink(),
'SELECT value i FROM c join i in c.list',
function (err, feed, options) {
if (err) throw err;
var uniqueArray = feed
.filter(function(item, pos) { return feed.indexOf(item) == pos;});
getContext().getResponse().setBody(uniqueArray);
});
if (!isAccepted) throw new Error('The query was not accepted by the server.');
}
You can read more how to utilize DocumentDB serverside programming from
"Azure Cosmos DB server-side programming: Stored procedures, database triggers, and UDFs".
You can use 'Distinct', it is supported now:
SELECT distinct value i FROM c join i in c.list
Results in: [1, 2, 3, 4]

Add map to list if no map with such key in list ELSE increment value in map

I am looking for a way to insert a new map in a list if no map with such key in this list already exists, if exists -> increment valueNum.
mylist [
mymap1: {
key1: valueNum,
key2: otherValue
}
]
Is it possible in one query, with returning of item?
I simplified my schema to few additional tables without such deep structures.

Differences in query result format from DocDb

I'm wrapping access to a DocDB collection in a C# class and are experiences some pain in mapping the more advanced queries. While trying to debug using the Query Explorer I noticed some differences in the json returned:
select * from collection
will return
[{ "id" : "1", "names" : [ {"name" : "first"}, {"name" : "second"}]}]
while
select c from collection c
will return
[{ "c" : { "id" : "1", "names" : [ {"name" : "first"}, {"name" : "second"}]}}]
Please notice how the results are nested below a "c" property!
This difference seems to cause issues when I need to create queries that uses named selects and having the c# library map results back into a type. An example of such a query is
select c from collection c join n in c.names WHERE n.name = "first"
This query MUST use the 'c' for selection (* is not allowed) so the internal mapping returns the correct number of results but each returned item is not mapped (likely because it expects the json properties at the topmost level and not beneath a "c" property).
Does anyone know how I can get the DocumentQuery C# api (from nuget version 1.5.3) to understand that results to map are nested below a named result property?
After reading under the SELECT clause I found the VALUE keyword that just returns the json which makes the C# driver happy again.
So my query should end up reading
select value c from collection c join n in c.names WHERE n.name = "first"

Resources