How to query in top level array in couchbase? - java

I have a couchbase collection where I am storing each record as an array as below
[
{
"id": 1237,
"customerId": 1561
},
{
"id": 1238,
"customerId": 1562
}
]
Now I want to query this array where customerId = xyz;
How do I achieve this using N1 query?

The document it self is scalar ARRAY vs OBJECT it is hard to create index and might need primary index.
INSERT INTO default VALUES("f01", [ { "id": 1237, "customerId": 1561 }, { "id": 1238, "customerId": 1562
} ]);
SELECT u.*
FROM default AS d
UNNEST d AS u
WHERE u.customerId = 1561;

Related

Nested Select Query With Mongo Repository

We use SpringBoot with mongo and have a document like this:
[{
"id": "classicId",
"name": "classicName",
"models": [
{
"id": "AnotherId",
"name": "AnotherSomeName"
},
{
"id": "RequiredId",
"name": "SomeName"
}
]
}]
The id in the array models is unique.
The input could be just any id in the models array. So the user will just give us the value "AnotherId" in order to find the document.
How can we do that in java using the mongo template or mongo repository?
With MongoRepository you could do something like:
public Optional<YourObject> getByModelId(theVariableWithTheValue) {
Query query = new Query().addCriteria(Criteria.where("models.id").is(theVariableWithTheValue));
List<YourObject> result = mongoTemplate.find(query, YourObject.class);
return result.isEmpty() ? Optional.empty() : Optional.of(result.get(0));
}

Query DynamoDb Global Secondary Index

i am trying out dynamodb locally and got the following table:
"Table": {
"AttributeDefinitions": [
{
"AttributeName": "hashKey",
"AttributeType": "S"
},
{
"AttributeName": "sortKey",
"AttributeType": "S"
},
{
"AttributeName": "full_json",
"AttributeType": "S"
}
],
"TableName": "local",
"KeySchema": [
{
"AttributeName": "hashKey",
"KeyType": "HASH"
},
{
"AttributeName": "sortKey",
"KeyType": "RANGE"
}
],
"TableStatus": "ACTIVE",
"CreationDateTime": "2021-10-01T15:18:04.413000+02:00",
"ProvisionedThroughput": {
"LastIncreaseDateTime": "1970-01-01T01:00:00+01:00",
"LastDecreaseDateTime": "1970-01-01T01:00:00+01:00",
"NumberOfDecreasesToday": 0,
"ReadCapacityUnits": 5,
"WriteCapacityUnits": 1
},
"TableSizeBytes": 1066813,
"ItemCount": 23,
"TableArn": "arn:aws:dynamodb:ddblocal:000000000000:table/local",
"GlobalSecondaryIndexes": [
{
"IndexName": "sortKeyIndex",
"KeySchema": [
{
"AttributeName": "sortKey",
"KeyType": "HASH"
}
],
"Projection": {
"ProjectionType": "ALL"
},
"IndexStatus": "ACTIVE",
"ProvisionedThroughput": {
"ReadCapacityUnits": 10,
"WriteCapacityUnits": 1
},
"IndexSizeBytes": 1066813,
"ItemCount": 23,
"IndexArn": "arn:aws:dynamodb:ddblocal:000000000000:table/local/index/sortKeyIndex"
}
]
}
I want to query it with Java like this:
Index index = table.getIndex("sortKeyIndex");
ItemCollection<QueryOutcome> items2 = null;
QuerySpec querySpec = new QuerySpec();
querySpec.withKeyConditionExpression("sortKey > :end_date")
.withValueMap(new ValueMap().withString(":end_date","2021-06-30T07:49:22.000Z"));
items2 = index.query(querySpec);
But it throws a Exception with "QUery Key Condition not supported". I dont understand this, because in the docs, the "<" operator is described as regular operation. Can anybody help me
DDB Query() requires a key condition that includes an equality check on the hash/partition key.
You must provide the name of the partition key attribute and a single
value for that attribute. Query returns all items with that partition
key value. Optionally, you can provide a sort key attribute and use a
comparison operator to refine the search results.
In other words, the only time you can really use Query() is when you have a composite primary key (hash + sort).
Without a sort key specified as part of the key for the table/GSI, Query() acts just like GetItem() returning a single record with the given hash key.

JSONPath: Get root array object using filter of child value

Im trying to get JSONPath expression to filter my JSON and get whole sport object using value of child array.
I have following JSON:
[{
"name": "Soccer",
"regions": [{
"name": "Australia",
"leagues": [{
"name": "Australia league",
"inplay": 5,
}
]
}
]
}, {
"name": "Tennis",
"regions": [{
"name": "Germany",
"leagues": [{
"name": "Germany league",
"inplay": 0,
}
]
}
]
}
]
I need to get whole sport object where "inplay == 0" using JsonPath expression.
Result should look like that:
{
"name": "Tennis",
"regions": [{
"name": "Germany",
"leagues": [{
"name": "Germany league",
"inplay": 0,
}
]
}
]
}
Regions and Leagues count can be > 1
Therefore $[?(#.regions[0].leagues[0].inplay == 0)] is not suitable
Tried $[?(#.regions[*].leagues[*].inplay == 0)] but it doesnt work
This works for me
$[?(#.regions[0].leagues[0].inplay == 0)]
Since this is not directly supported (as of now) in JayWay JSONPath we leverage contains as a workaround:
$[?(#.regions..inplay contains '0')]
Note: It may look like contains would work similar to a 'like' operator or instr function but this is not the case here. If the inplay value contains a 0, e.g. 10 it would not pull the record (according to my tests;)

Jayway JsonPath filtering with predicates

I've recently taken up Jayway JsonPath and I've had trouble with how the inpath filtering works.
So my JSON looks like this:
At the top I have shareables. These shareables have an array called user, which contains an ID and a name, and they also contain an item called dataset, which can contain any json.
These shareables can exist within the dataset as well.
My working JSON looks like this:
{
"shareable": {
"user": [
{
"ID": 1,
"Name": "Bob"
},
{
"ID": 2,
"Name": "Charles"
}
],
"dataSet": [
{
"insulinMeasurement":
{
"timestamp": "Tuesday Morning",
"measurement": 174,
"unit": "pmol/L"
}
},
{
"insulinMeasurement":
{
"timestamp": "Tuesday Noon",
"measurement": 80,
"unit": "pmol/L"
}
},
{ "shareable": {
"user": [
{
"ID": 3,
"Name": "Jim"
}
],
"dataSet": [
{
"insulinMeasurement":
{
"timestamp": "Tuesday Evening",
"measurement": 130,
"unit": "pmol/L"
}
}
]
}
},
{ "unshareable": {
"user": [
{
"ID": 2,
"Name": "Bob"
}
],
"dataSet": [
{
"insulinMeasurement":
{
"timestamp": "Tuesday Night",
"measurement": 130,
"unit": "pmol/L"
}
}
]
}
}
]
}
}
So what I want is, all shareables that have a user with a certain ID. So I figured the path I would use would look like this:
$..shareable[ ?(#.user[*].ID == 1 )]
which here has a hardcoded ID. This returns nothing while
$..shareable[ ?(#.user[0].ID == 1 )]
returns any shareable where the first ID is 1.
I also tried something along the lines of
$..shareable[ ?(#.user[?(#.ID == 1)]
which I figure should return any shareable that has a user with an ID of 1.
Am I going about this the wrong way? Do I need to somehow iterate through the user objects that exist?
Well, I figured it out, so if anyone stumbles across this, the query should look as follows:
$..shareable[?( " + user + " in #.user[*].ID )]
where user is just the int of the userId. Basically the right hand side creates a list of all IDs that shareable contains, and checks if the requested ID exists therein.

Is aggregation (count) on dimension but not on metrics supported by Druid

For example there are two dimensions: [country, website] and one metric: [PV].
I want to know the average PV of website for each country.
To make it, it's easy to get the total PV in each country, however it's difficult to get the count of website in each country, furthermore the expect result is the total PV(in each country) divided by the count of website(in each country).
What I can do is apply "groupBy" query by country & website as below, and then group the result by country outside in my application. It's very very very slow, because the query extract lots of data from Druid and most of them is meaningless just for a sum.
{
"queryType": "groupBy",
"dataSource": "--",
"dimensions": [
"country",
"website"
],
"granularity": "all",
"intervals": [
"--"
],
"aggregations": [
{
"type": "longSum",
"name": "PV",
"fieldName": "PV"
}
]
}
Any one can help with this? I'm wondering it's impossible such a common query is not supported by Druid.
Thanks in advance.
To be clear, I describe my expected result by SQL, if you have known what I want to do or not familiar to SQL, please ignore the following part.
SELECT country, sum(a.PV_all) / count(a.website) as PV_AVG FROM
(SELECT country, website, SUM(PV) as PV_all FROM DB GROUP BY country, website ) a
GROUP BY country
Have you tried using a nested groupBy query ? druid support that.
In nutshell you can have something like
{
"queryType": "groupBy",
"dataSource":{
"type": "query",
"query": {
"queryType": "groupBy",
"dataSource": "yourDataSource",
"granularity": "--",
"dimensions": ["country", "website"],
"aggregations": [
{
"type": "longSum",
"name": "PV",
"fieldName": "PV"
}
],
"intervals": [ "2012-01-01T00:00:00.000/2020-01-03T00:00:00.000" ]
}
},
"granularity": "all",
"dimensions": ["country"],
"aggregations": [
----
],
"intervals": [ "2012-01-01T00:00:00.000/2020-01-03T00:00:00.000" ]
}

Categories