I have a list of defined objects:
[{"name":"name1", "age":25}, {"name":"name2", "age":27}]
and I would like to return records that are the same
Is there any way in Cosmos DB to perform the following query?
select * from c
where c in ({"name":"name1", "age":25}, {"name":"name2", "age":27})
my records are like this:
[
{
"name":"name1",
"age":25,
"height":165
},
{
"name":"name2",
"age":27,
"height":169
},
{
"name":"name3",
"age":35,
"height":185
}
]
The query would return this result:
[
{
"name":"name1",
"age":25,
"height":165
},
{
"name":"name2",
"age":27,
"height":169
}
]
You can use ARRAY_CONTAINS
SELECT * FROM c where ARRAY_CONTAINS([{"name":"name1", "age":25}, {"name":"name2", "age":27}],{"name":c.name,"age":c.age})
Note : Might be useful for others as in the comment.
Related
I am just no understanding how user defined functions in CosmosDB works.
Why is the my UDF in Cosmos DB returning results equal to the number of records in the table?
My table has 4 records currently.
Here are the records -
{
"users": [
{
"partitionKey": "user",
"userPhoneNumber": "14168000000",
"userDisplayName": "Test User 1"
},
{
"partitionKey": "user",
"userPhoneNumber": "18055678978",
"userDisplayName": "Test User 2"
},
{
"partitionKey": "user",
"userPhoneNumber": "17202228799",
"userDisplayName": "Test User 3"
},
{
"partitionKey": "user",
"userPhoneNumber": "17780265987",
"userDisplayName": "Test User 4"
}
]
}
Here is my UDF -
function findUserByPhoneNumber(users, contactNumbers){
var result;
for (let i = 0; i < contactNumbers.length; i++) {
if (contactNumbers[i] == "14168000000") {
result = contactNumbers[i];
}
return result;
}
Here is my SQL -
SELECT udf.findUserByPhoneNumber(c,["14168000000","17200000000"]) FROM c
And here is the result I am getting -
[
{
"$1": "14168000000"
},
{
"$1": "14168000000"
},
{
"$1": "14168000000"
},
{
"$1": "14168000000"
}
]
I am only expecting one record to be returned.
The SELECT statement in your query will never help you filter items in your query. If you want to filter you should use WHERE in your query. While you could use a UDF in a WHERE statement that returns e.g. a boolean you should typically avoid it as the database can not use it indexes to efficiently retrieve your data and will have to use your UDF on every document to calculate if it should be retrieved.
For your scenario the query could be:
SELECT *
FROM c
WHERE ARRAY_CONTAINS(['14168000000', '17200000000'], c.userPhoneNumber)
The reason your UDF always returns 14168000000 is because you always use the array ['14168000000', '17200000000'] as input in your UDF and check if any of those values equals 14168000000 and return that.
Question:
I am trying SQL query as the image showed below,I want it to be grouped by the same timestamp
expected output:
[
{
"tag1": {
"TagName": "PV1-input-power-L(10W)",
"Value": 0
},
"tag2": {
"TagName": "Sunshine-Display-Value",
"Value": 0
},
"tag3": {
"TagName": "TotalEnergy-(100kWh)_1",
"Value": 0
},
"timestamp": "2020-03-27T02:40:18Z"
}
]
sample document:
You can use User Defined Functions.
Here is the data from my containers
Here is the function I have created. I named it CustomArray.
function userDefinedFunction(input){
var obj={};
input.forEach(function(element,index){
obj["tag"+index] = {
TagName :element.TagName,
Value: element.Value
};
}); return obj;}
Here, I run the UDF with my select statement
It returns the following data.
Schema is very close to what you are looking for. I think you can make it better by changing some jscript in UDF.
I hope this helps!
I would like to turn this resultset
[
{
"Document": {
"JsonData": "{\"key\":\"value1\"}"
}
},
{
"Document": {
"JsonData": "{\"key\":\"value2\"}"
}
}
]
into this
[
{
"key": "value1"
},
{
"key": "value2"
}
]
I can get close by using a query like
select value c.Document.JsonData from c
however, I end up with
[
"{\"key\":\"value1\"}",
"{\"key\":\"value2\"}"
]
How can I cast each value to an individual JSON fragment using the SQL API?
As David Makogon said above, we need to transform such data within our app. We can do as below:
string data = "[{\"key\":\"value1\"},{\"key\":\"value2\"}]";
List<Object> t = JsonConvert.DeserializeObject<List<Object>>(data);
string jsonData = JsonConvert.SerializeObject(t);
Screenshot of result:
Imagine I have the data in Cosmos
[
{
"id": "FCEC01CD-A6E9-4DEA-8DD5-89711B5B05A1",
"sub": [
{
"id": 1,
"v": false
},
{
"id": 2,
"v": false
}
]
]
and I want to query for all id's that have all (sibbeling) 'sub' items having v=false
what query syntax would work?
(ARRAY_CONTAINS would not work, since that gives an 'any' result)
Thanks!
You need a user-defined function for this.
function arrayAllMatch(arr) {
for(i=0; i < arr.length; i++) {
if (arr[i].v === true) {
return false;
}
}
return true;
}
Then call within query (also include ARRAY_CONTAINS because it can use the index to reduce the number of calls to the UDF):
SELECT *
FROM c
WHERE ARRAY_CONTAINS(c.sub, {"v" : false }, true)
AND udf.arrayAllMatch(c.sub)
I have two collections A and B in Meteor. For A I have a publication where I filter out a range of documents in A. Now I want to create a publications for B where I publish all documents in B that have a field B.length matching A.length.
I have not been able to find any example where this is shown but I feel it must be a standard use case. How can this be done in Meteor?
This is a common pattern for reywood:publish-composite
import { publishComposite } from 'meteor/reywood:publish-composite';
publishComposite('parentChild', {
const query = ... // your filter
find() {
return A.find(query, { sort: { score: -1 }, limit: 10 });
},
children: [
{
find(a) {
return B.find({length: a.length });
}
}
]
});
This is a quite different pattern than serverTransform as on the client you end up with two collections, A and B, as opposed to a synthetic single collection A that has some fields of of B. The latter is more like a SQL JOIN.
Use serverTransform
Meteor.publishTransformed('pub', function() {
const filter = {};
return A.find(filter)
.serverTransform({
'B': function(doc) {
return B.find({
length: doc.length
}); //this will feed directly into miniMongo as if it was a seperate publication
}
})
});