How can I COUNT(DISTINCT) in ServiceStack Ormlite? - ormlite-servicestack

I'm writing a paged query in ServiceStack's OrmLite, selecting the total records and the ids of records in the page range. Assuming query is some arbitrary SqlExpression selecting a bunch of records:
var idQuery = query.SelectDistinct(r => r.Id);
var ids = Db.Column<int>(idQuery.Skip(request.Skip).Take(request.Take));
var total = Db.Count(idQuery);
OrmLite generates two queries, one for the ids:
SELECT DISTINCT ...
And one for the total:
SELECT COUNT(*)
I'm trying to get OrmLite to generate SELECT COUNT(DISTINCT Id) for the total query, or perform an equivalent. Is this possible?

In previous versions of OrmLite you would need to use Custom SQL:
var count = db.Scalar<long>(idQuery.Select("COUNT(DISTINCT Id)"));
I've just added support for Sql.CountDistinct in this commit which will let you use a Typed API:
var count = db.Scalar<long>(idQuery.Select(x => Sql.CountDistinct(x.Id)));
This change is available from v4.0.61 that's now available on MyGet.

Related

How to get live table row count in DynamoDb programmatically in ASP.NET Core?

I wrote something like below code in my ASP.NET WEB API. I want to get the live row count t0 display in my application. The problem with the below code is it's showing Scanned count as 7134. But actual value is in millions.
var cancellationToken = new CancellationToken();
AmazonDynamoDBClient client = new AmazonDynamoDBClient();
var request = new ScanRequest
{
TableName = "exampleTable",
Select = Select.COUNT
};
var response = client.ScanAsync(request, cancellationToken).Result;
var totalCount = response.Count.ToString();
return totalCount;
What do you mean by 'live' row count?
Also, if you have only a few pieces of code that insert into your Dynamo table you could insert a record specifically for maintaining count, and then update this record's counter whenever inserting / deleting from the table.. It's more work, but may be better than incurring the costs involved in scanning millions of records, multiple times a day.

Document count query ignores PartitionKey

I am looking to get the count of all documents in a chosen partition. The following code however will return the count of all documents in the collection and costs 0 RU.
var collectionLink = UriFactory.CreateDocumentCollectionUri(databaseId, collectionId);
string command = "SELECT VALUE COUNT(1) FROM Collection c";
FeedOptions feedOptions = new FeedOptions()
{
PartitionKey = new PartitionKey(BuildPartitionKey(contextName, domainName)),
EnableCrossPartitionQuery = false
};
var count = client.CreateDocumentQuery<int>(collectionLink, command, feedOptions)
.ToList()
.First();
adding a WHERE c.partition = 'blah' clause to the query will work, but costs 3.71 RUs with 11 documents in the collection.
Why would the above code snippet return the Count of the whole Collection and is there a better solution to for getting the count of all documents in a chosen partition?
If the query includes a filter against the partition key, like SELECT
* FROM c WHERE c.city = "Seattle", it is routed to a single partition. If the query does not have a filter on partition key, then it is
executed in all partitions, and results are merged client side.
You could check the logical steps the SDK performs from this official doc when we issue a query to Azure Cosmos DB.
If the query is an aggregation like COUNT, the counts from individual
partitions are summed to produce the overall count.
So when you just use SELECT VALUE COUNT(1) FROM Collection c, it is executed in all partitions and results are merged client side.
If you want to get the count of all documents in a chosen partition, you just add the where c.partition = 'XX' filter.
Hope it helps you.
I believe this is actually a bug since I am having the same problem with the partition key set in both the query and the FeedOptions.
A similar issue has been reported here:
https://github.com/Azure/azure-cosmos-dotnet-v2/issues/543
And Microsoft's response makes it sound like it is an SDK issue that is x64-specific.

What is the order of Attributes in the result of the Query in DynamoDB (.net)?

In .net I specify
QueryOperationConfig queryConfig = new QueryOperationConfig
{
Filter = queryFilter,
IndexName = "PARTNAME-NAME-index",
Limit = 1,
BackwardSearch = desc,
Select = SelectValues.SpecificAttributes,
AttributesToGet = new List<string>
{ "PARTNAME","ID", "NAME","WEIGHT" }
};
But in Query results Attributes order is
WEIGHT, ID, PARTNAME, NAME
In my table PARTNAME is Hashkey, ID is Sortkey, and I have GSI PARTNAME-NAME-index combined of PARTNAME and NAME
How can I specify the needed Attributes order,
or how how are they ordered by default?
Firstly, you are using the legacy AttributesToGet parameter.
This is a legacy parameter. Use ProjectionExpression instead.
Answer:-
DynamoDB doesn't guarantee the order of the attributes in results. Primarily, DynamoDB is a key-value store. You need to get the value for the specific key from the result.
Please note that this is not like SELECT statement on RDBMS. This is a NoSQL database and it is completely different from RDBMS.

How to query range key programmatically in DynamoDB

How to query range key programmatically in DynamoDB, I am using .Net AWSSDK ,I am able to query on Hash key with below code :
GetItemRequest request = new GetItemRequest
{
TableName = tableName
};
request.Key = new Dictionary<string,AttributeValue>();
request.Key.Add("ID",new AttributeValue { S = PKValue });
GetItemResponse response = client.GetItem(request);
Please suggest,
Thanks in advance.
There are two kinds of primary key in DynamoDB: Hash-only or Hash-Range.
In the above code I guess your table is Hash-only and you use the hash key to retrieve an element with hashkey equals to PKValue.
If your table is in H-R schema and you want to retrieve a specific element with a hashKey and rangeKey, you can reuse the above code and in addition, add the {"RangeKey", new AttributeValue } into your your request.KEY
On the other hand, query means a different thing in DynamoDB. Query will return you a list of rows sorted in some order.

Linq query returning same row 12 times

Hi i have written one linq query to fetch records from entity model. I am getting perfect number of records but all are same.
here is my query
Entities.TEST.Where(a => a.ID.ToUpper().Equals(ID.ToUpper())).OrderBy(s => s.NAME).ToList();
Am I missing something?
You need to make sure your Entity Key in your Entity Data Model is unique.
So in your example, ID should be the entity key for your Test entity
Your query should work, i have a similar sample that works for northwind DB:
var ctx = new NorthwindEntities();
var emp = ctx.Employees.Where(e => e.TitleOfCourtesy.Equals("ms.", StringComparison.OrdinalIgnoreCase)).OrderBy(n => n.FirstName).ToList();
Please check your query in LinqPad. You will see the results and the generated SQL.
Replace Equals with == and you can go

Resources