How to check if a json path/value entries exists in a huge json object in oracle sql? - oracle

Let's say the json object is like :
{
"title":"<title goes here>",
"version":"1.0.0",
"name":"<name goes here>",
"features": {
"feature-id1":{
"id":"090ccd9c-8930-4aa9-9aa3-f9c8e6747a27",
"name":"feature1",
"version":"1.0.0"
}
"feature-id2":{
"id":"932twe8e-2184-4er9-5qw3-g4e9w9821w71",
"name":"feature2",
"version":"1.0.0"
}
...
}
}
I want to check whether there exists a json path/value entries (or) a nested json object in the above json data.
I have tried with json_exists(json_column,'$.features?(#."feature-id1" == "{"id": "090ccd9c-8930-4aa9-9aa3-f9c8e6747a27","name":"feature1","version":"1.0.0"}")');
But this is giving me an error "JZN-00229: Missing parenthesis in paranthetical expression".
Can't we use json_exists() to check for json objects/arrays with values?
In Postgresql this can be achieved by using the '#>' operator : json_data->'features'->'feature-id1' #> 'provide the json value'
Is there a way to achieve the same in Oracle SQL? I'm using Oracle 19c with latest patch(19.15).

At least in Oracle (I don't know other database products - you mention Postgre and say it has capabilities that Oracle doesn't have), comparison filters like you are trying to apply only work for scalar values, not for nested objects.
If I understand what you are trying to do, then in Oracle you would do that with something like
json_exists(json_column,'$."features"."feature-id1"?(
#."id" == "090ccd9c-8930-4aa9-9aa3-f9c8e6747a27"
&& #."name" == "feature1"
&& #."version" == "1.0.0"
)'
)
although this is not exactly equivalent to what you were trying to do. Namely, this filter only ensures the existence of a key "feature-id1" with value a nested object that has at least the three keys "id", "name" and "version", with the prescribed values - but it may also have other keys. So the object value of "feature-id1" may not be equal to the prescribed object in your attempt, which has exactly three keys, no more. Will that work for you? Only you know.

Related

How to return a query from cosmos db order by date string?

I have a cosmos db collection. I need to query all documents and return them in order of creation date. Creation date is a defined field but for historical reason it is in string format as MM/dd/yyyy. For example: 02/09/2019. If I just order by this string, the result is chaos.
I am using linq lambda to write my query in webapi. I have tried to parse the string and try to convert the string. Both returned "method not supported".
Here is my query:
var query = Client.CreateDocumentQuery<MyModel>(CollectionLink)
.Where(f => f.ModelType == typeof(MyModel).Name.ToLower() && f.Language == getMyModelsRequestModel.Language )
.OrderByDescending(f => f.CreationDate)
.AsDocumentQuery();
Appreciate for any advice. Thanks. It will be huge effort to go back and modify the format of the field (which affects many other things). I wish to avoid it if possible.
Chen Wang.Since the order by does not support derived values or sub query(link),so you need to sort the derived values by yourself i think.
You could construct the MM/dd/yyyy to yyyymmdd by UDF in cosmos db.
udf:
function getValue(datetime){
return datetime.substring(6,10)+datetime.substring(0,2)+datetime.substring(3,5);
}
sql:
SELECT udf.getValue(c.time) as time from c
Then you could sort the array by property value of class in c# code.Please follow this case:How to sort an array containing class objects by a property value of a class instance?

Spring Data Mongodb - findBy query with OR clause on same field

I'm working on mongo with spring data and using the query "findBy" based on property fields.
My goal will be find same value across multiple properties by OR clause like this:
List<Event> findByCreatorOrOrganizersOrGuests(User user);
this query involves 3 properties: "creator", "organizers" and "guests" that are a single value (creator) and 2 lists (organizers and guests) that contains the same class type (User)
at compile time I receive this error:
org.springframework.data.repository.query.ParameterOutOfBoundsException: Invalid parameter index! You seem to have declare too little query method parameters!
Do I need to repeat the same parameter 3 times? There's no workaround?
thanks
The using of Mongo queries for lists are not so efficient even if you define it with an index.
Another important thing is that the query:
List<Event> findByCreatorOrOrganizersOrGuests(User user);
includes some syntax errors (The MongoDB expects to get 3 parameters as variables int the ( ) relatively to the findBy keys, the return value should be inserted into a list object, and I am not sure that the Or in the find query is legal syntax.
As a concept the DB documents should have a good ability to be searched, cause it is the most expensive action.
When find using OR in MongoDB the direct query should looks like that:
def events = find({ $or: [ { user.username: { $lt: 20 } }, { price: 10 } ] } )
While searching in a list this is should be different, so please follow the links I attached.
When I try to think of the use you are looking for, I would suggest a different aspect. If the events is what interest you please read about the AbstractPersistenceEventListener. By define the appropriate
void onPostInsert(entity) {}
void onPostUpdate(entity) {}
void onPostDelete(entity) {}
You get all the events for each of the objects you want to listen to.
Here are 2 a great examples:
Example 1
Example 2

How to handle missing rows in a dependent table

I have two Sql Server tables accessed through Entity Framework 4. They are joined by a single key with 0 to 1 rows on the dependent side of the join. Here is my linq query.
var typeDtoList = from type in typeList
select (new DxStudioTypeDto(parent,
isChildrenLoadOnDemand,
businessFacade,
server,
database,
type.typeGuid,
type.typeName,
type.writerName,
type.managerName,
type.Reporting_Type.MRef_Status,
type.Reporting_Type.Exists_In_Drop));
Obviously, if the Reporting_Type returns zero rows, the linq expression throws a null reference exception on the last two parameters of the DxStudioTypeDto constructor:
type.Reporting_Type.MRef_Status,
type.Reporting_Type.Exists_In_Drop));
Is there a way to detect the absence of a Reporting_Type row and substitute a default string? DxStudioTypeDto is an immutable type, so I need all the parameters available when I instanciate a new object. Any other strategies for this situation?
Did you try this?
((type.Reporting_Type == null) ? "some default value" : type.Reporting_Type.MRef_Status)
I know sometimes the EF engine returns a "the provider does not support this operation" for this kind of thing, but it's worth a try.

LINQ syntax where string value is not null or empty

I'm trying to do a query like so...
query.Where(x => !string.IsNullOrEmpty(x.PropertyName));
but it fails...
so for now I have implemented the following, which works...
query.Where(x => (x.PropertyName ?? string.Empty) != string.Empty);
is there a better (more native?) way that LINQ handles this?
EDIT
apologize! didn't include the provider... This is using LINQ to SQL
http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=367077
Problem Statement
It's possible to write LINQ to SQL that gets all rows that have either null or an empty string in a given field, but it's not possible to use string.IsNullOrEmpty to do it, even though many other string methods map to LINQ to SQL.
Proposed Solution
Allow string.IsNullOrEmpty in a LINQ to SQL where clause so that these two queries have the same result:
var fieldNullOrEmpty =
from item in db.SomeTable
where item.SomeField == null || item.SomeField.Equals(string.Empty)
select item;
var fieldNullOrEmpty2 =
from item in db.SomeTable
where string.IsNullOrEmpty(item.SomeField)
select item;
Other Reading:
1. DevArt
2. Dervalp.com
3. StackOverflow Post
This won't fail on Linq2Objects, but it will fail for Linq2SQL, so I am assuming that you are talking about the SQL provider or something similar.
The reason has to do with the way that the SQL provider handles your lambda expression. It doesn't take it as a function Func<P,T>, but an expression Expression<Func<P,T>>. It takes that expression tree and translates it so an actual SQL statement, which it sends off to the server.
The translator knows how to handle basic operators, but it doesn't know how to handle methods on objects. It doesn't know that IsNullOrEmpty(x) translates to return x == null || x == string.empty. That has to be done explicitly for the translation to SQL to take place.
This will work fine with Linq to Objects. However, some LINQ providers have difficulty running CLR methods as part of the query. This is expecially true of some database providers.
The problem is that the DB providers try to move and compile the LINQ query as a database query, to prevent pulling all of the objects across the wire. This is a good thing, but does occasionally restrict the flexibility in your predicates.
Unfortunately, without checking the provider documentation, it's difficult to always know exactly what will or will not be supported directly in the provider. It looks like your provider allows comparisons, but not the string check. I'd guess that, in your case, this is probably about as good of an approach as you can get. (It's really not that different from the IsNullOrEmpty check, other than creating the "string.Empty" instance for comparison, but that's minor.)
... 12 years ago :) But still, some one may found it helpful:
Often it is good to check white spaces too
query.Where(x => !string.IsNullOrWhiteSpace(x.PropertyName));
it will converted to sql as:
WHERE [x].[PropertyName] IS NOT NULL AND ((LTRIM(RTRIM([x].[PropertyName])) <> N'') OR [x].[PropertyName] IS NULL)
or other way:
query.Where(x => string.Compare(x.PropertyName," ") > 0);
will be converted to sql as:
WHERE [x].[PropertyName] > N' '
If you want to go change the type of the collection from nullable type IEnumerable<T?> to non-null type IEnumerable<T> you can use .OfType<T>().
.OfType<T>() will remove null values and return a list of the type T.
Example: If you have a list of nullable strings: List<string?> you can change the type of the list to string by using OfType<string() as in the below example:
List<string?> nullableStrings = new List<string?> { "test1", null, "test2" };
List<string> strings = nullableStrings.OfType<string>().ToList();
// strings now only contains { "test1", "test2" }
This will result in a list of strings only containing test1 and test2.

Entity Framework - "Unable to create a constant value of type 'Closure type'..." error

Why do I get the error:
Unable to create a constant value of type 'Closure type'. Only
primitive types (for instance Int32, String and Guid) are supported in
this context.
When I try to enumerate the following Linq query?
IEnumerable<string> searchList = GetSearchList();
using (HREntities entities = new HREntities())
{
var myList = from person in entities.vSearchPeople
where upperSearchList.All( (person.FirstName + person.LastName) .Contains).ToList();
}
Update:
If I try the following just to try to isolate the problem, I get the same error:
where upperSearchList.All(arg => arg == arg)
So it looks like the problem is with the All method, right? Any suggestions?
It looks like you're trying to do the equivalent of a "WHERE...IN" condition. Check out How to write 'WHERE IN' style queries using LINQ to Entities for an example of how to do that type of query with LINQ to Entities.
Also, I think the error message is particularly unhelpful in this case because .Contains is not followed by parentheses, which causes the compiler to recognize the whole predicate as a lambda expression.
I've spent the last 6 months battling this limitation with EF 3.5 and while I'm not the smartest person in the world, I'm pretty sure I have something useful to offer on this topic.
The SQL generated by growing a 50 mile high tree of "OR style" expressions will result in a poor query execution plan. I'm dealing with a few million rows and the impact is substantial.
There is a little hack I found to do a SQL 'in' that helps if you are just looking for a bunch of entities by id:
private IEnumerable<Entity1> getByIds(IEnumerable<int> ids)
{
string idList = string.Join(",", ids.ToList().ConvertAll<string>(id => id.ToString()).ToArray());
return dbContext.Entity1.Where("it.pkIDColumn IN {" + idList + "}");
}
where pkIDColumn is your primary key id column name of your Entity1 table.
BUT KEEP READING!
This is fine, but it requires that I already have the ids of what I need to find. Sometimes I just want my expressions to reach into other relations and what I do have is criteria for those connected relations.
If I had more time I would try to represent this visually, but I don't so just study this sentence a moment: Consider a schema with a Person, GovernmentId, and GovernmentIdType tables. Andrew Tappert (Person) has two id cards (GovernmentId), one from Oregon (GovernmentIdType) and one from Washington (GovernmentIdType).
Now generate an edmx from it.
Now imagine you want to find all the people having a certain ID value, say 1234567.
This can be accomplished with a single database hit with this:
dbContext context = new dbContext();
string idValue = "1234567";
Expression<Func<Person,bool>> expr =
person => person.GovernmentID.Any(gid => gid.gi_value.Contains(idValue));
IEnumerable<Person> people = context.Person.AsQueryable().Where(expr);
Do you see the subquery here? The generated sql will use 'joins' instead of sub-queries, but the effect is the same. These days SQL server optimizes subqueries into joins under the covers anyway, but anyway...
The key to this working is the .Any inside the expression.
I have found the cause of the error (I am using Framework 4.5). The problem is, that EF a complex type, that is passed in the "Contains"-parameter, can not translate into an SQL query. EF can use in a SQL query only simple types such as int, string...
this.GetAll().Where(p => !assignedFunctions.Contains(p))
GetAll provides a list of objects with a complex type (for example: "Function"). So therefore, I would try here to receive an instance of this complex type in my SQL query, which naturally can not work!
If I can extract from my list, parameters which are suited to my search, I can use:
var idList = assignedFunctions.Select(f => f.FunctionId);
this.GetAll().Where(p => !idList.Contains(p.FunktionId))
Now EF no longer has the complex type "Function" to work, but eg with a simple type (long). And that works fine!
I got this error message when my array object used in the .All function is null
After I initialized the array object, (upperSearchList in your case), the error is gone
The error message was misleading in this case
where upperSearchList.All(arg => person.someproperty.StartsWith(arg)))

Resources