Is there any DATEADD-like functionality in Cosmos DB SQL API?
Fairly new to the SQL API for Cosmos DB and am looking for a functionality that would be close to DATEADD in SQL. Is there any? I've reviewed the system functions on the MS website but couldn't find any.
SELECT count(1)
FROM c
where c.composed_at < dateadd("day",-30,c.composed_at)
User Defined Functions maybe the route to take.
https://learn.microsoft.com/en-us/azure/cosmos-db/sql-query-udfs
You could define an udf in your cosmos db collection.
function getLastMonth(){
var date = new Date();
var a = date.setDays(-30);
return a;
}
Modify your sql to :
SELECT * FROM c where c.composed_at < udf.getLastMonth()
Note: udf.getLastMonth() returns Unix time stamp , you need to match the format.
Hope it helps you.
Related
I played with the same code that uses the #Query annitation e.g.
#Query(value = "SELECT * FROM c")
List<User> getAllUsers();
However, how do I do the equivalent of SQL Update e.g.?
#Query(value = "UPDATE c set c.firstName = #documentFirstName")
void updateUsersName(#Param("documentFirstName") String documentFirstName);
This example above doesn't work, is there some other syntax?
The Cosmos DB SQL API only supports the Select statement. Partially updating a document isn't supported yet.
If you are using the SDK, To update a document you have to use the Upsert-Method:
DocumentClient.UpsertDocumentAsync Method
UPDATE:
Partial update feature is supported since November 2021. The feature is GAed.
In Azure Cosmos DB (SQL API) the following query charges 9356.66 RU's:
SELECT * FROM Core c WHERE c.id = #id -- #id is a GUID
In contrast the following more complex query charges only 6.84 RU's:
SELECT TOP 10 * FROM Core c WHERE c.type = "Agent"
The documents in both examples are pretty small having a handful of attributes. Also the document collection does not use any custom indexing policy. The collection contains 105685 documents.
To me this sounds as if there is no properly working index on the "id" field in place.
How is this possible and how can this be fixed?
Updates:
Without the TOP keyword the second query charges 3516.35 RU's and returns 100000 records.
The partition key is "/partition" and its values are 0 or 1 (evenly distributed).
If you have partition collection you need to specify partition keyif you want to do request most efficiently. Cross-partition queries is really expensive (and slower) in cosmos, because partitions data can be stored in different places.
Try following:
SELECT * FROM Core c WHERE c.id = #id AND c.partition = #partition
Or, specify partition key in feed options if you're using CosmosDB SDK.
Let me know, if this helps.
I assume the solution is the same as posted here:
Azure DocumentDB Query by Id is very slow
I will close my own question once I am able to verify this with Microsoft Support.
is it possible to perform a case insensitive search on DocumnetDb?
Let's say I have a record with 'name' key and value as "Timbaktu"
This will work:
select * from json j where j.name = "Timbaktu"
This wont:
select * from json j where j.name = "timbaktu"
So how do yo do a case insensitive search?
Thanks in advance.
Regards.
There are two ways to do this. 1. use the built-in LOWER/UPPER function, for example,
select * from json j where LOWER(j.name) = 'timbaktu'
This will require a scan though. Another more efficient way is to store a "canonicalized" form e.g. lowercase and use that for querying. For example, the JSON would be
{ name: "Timbaktu", nameLowerCase: "timbaktu" }
Then use it for querying like:
select * from json j WHERE j.nameLowerCase = "timbaktu"
Hope this helps.
Cosmos recently added a case-insensitive option for string functions:
You now have an option to make these string comparisons
case-insensitive: Contains, EndsWith, StringEquals, and StartsWith.
and Significant performance improvements have been realized for these
string system functions. Each of these four string system functions
now benefit from an index and will therefore have much lower latency
and request unit (RU) consumption.
Announcement
Perhaps this is an ancient case, I just want to provide a workaround.
You could use UDF in azure cosmos db.
udf:
function userDefinedFunction(str){
return str .toLowerCase();
}
And use below sql to query results:
SELECT c.firstName FROM c where udf.lowerConvert(c.firstName) = udf.lowerConvert('John')
Let's say i have a table named User.
When I use the Entity Framework to get the records i do like this:
var db = new Context();
var users = db.Users;
It return all the users in my table. OK. If i do this:
var fooUsers = db.Users.Where(u => u.Name == 'foo');
It will give me all the users with name 'foo'. OK. My question is:
The entity framework make a query like:
select * from user where name = 'foo'
Or it load all the users and filter them on the server with lambda expression?
The Sql submitted to your database will contain your where clause. You can use SQL Server Profiler to watch as queries are submitted to your DB.
Entity Framework will translate such a query into a "Store Expression." That is, it will generate a database query -- assuming your data storage is a database -- that will be somewhat similar to the query you included in your question. It very well may name the columns, however, and there are likely to be some other differences.
From here http://msdn.microsoft.com/en-us/library/cc853327.aspx
When you create an ObjectQuery or LINQ query, the query may not be executed immediately. Query execution is deferred until the results are needed, such as during a foreach (C#) or For Each (Visual Basic) enumeration or when it is assigned to fill a List collection. Query execution begins immediately when you call the Execute method on an ObjectQuery or when you call a LINQ method that returns a singleton query, such as First or Any. For more information, see Object Queries and Query Execution (LINQ to Entities).
So when your query has a WHERE clause it will just load the results filtered by the database with the where.
I have list of words. I type in a word misspelled. Can I query the list using linq to get words that sounds like (soundex) the misspelled word?
I believe you can.
A quick google search came up with this link:
Code Snippet
from elt in SomeTable.AsEnumerable()
where SoundEx(elt.SomeWordsSoundExCode) == SoundEx("MyWord")
select elt;
If you want to use LINQ to SQL to query database, then you'll probably want to run the comparison on SQL side. You could use AsEnumerable, but then you'll need to implement the algorithm in C# and process the data in-memory.
I believe that LINQ to SQL doesn't provide any built-in method that would be translated to a call to the SOUNDEX function in SQL. However, you can add mapping for a user-defined SQL function (See for example this article). So, you could define your SQL function that performs the comparison and then write something like:
var db = new MyDatabaseContext();
var q = from w in db.Products
where db.SimilarSoundEx(w.Name, searchInput)
select w;