I am trying to create a dynamic query and I can't seem to find any documentation that would help. I have the following transaction. I would like to create a query that can potentially take any number of the fields, but it seems that whenever I create a query with a variable, it makes it required and if I don't provide it, they query errors out.
transaction QuantityChange {
o String partNumber
o String facilityId
o Double quantity
o invType invType
o appType application
o String refDocId optional
}
For instance, if I make the following query, I have to provide both Part and Facility or the query does not return.
query myTransactions{
description: "return all QuantityChange transactions made"
statement:
SELECT org.acme.trading.QuantityChange
WHERE ((partNumber == _$part) AND ( facilityId == _$facility))
}
Can anyone point me to some resources to help me make more dynamic queries?
There are examples where people have created many queries to cover the combinations of parameters they wish to query, but that is a simplistic approach and doesn't scale well.
You can build a dynamic query using the Composer API, specifically the buildQuery and query methods. These are available in the Client API and also the Runtime API so they can be used within Transaction logic.
https://hyperledger.github.io/composer/latest/api/client-businessnetworkconnection#buildquery
Related
(Note: all code examples are extremely simple. I know there are other ways to do such simple queries. The problem I am demonstrating, however, is a bigger deal for more complex queries).
There is a known issue with Spring JPA Repositories and paginated queries that I'm really hoping there is a good solution for. In JPQL, it is possible to use JOIN FETCH to specify that I want to eagerly fetch a related entity, rather than doing it lazily. This avoids the N+1 problem, among other things. JOIN FETCH requires that the owner of the association is included in the select clause. Here is a very simple example of the type of query I'm talking about:
#Query("""
SELECT p
FROM Person p
JOIN FETCH p.address
""")
Page<Person> getPeopleAndAddresses(Pageable page);
The problem with this kind of query is the pagination piece. When returning a Page, Spring will do the query I wrote but then also do a count query to get the total possible records. Spring appears to take my query exactly as written, and just replace SELECT p with SELECT COUNT(p). Doing this means that the owner of the JOIN FETCH association is no longer present in the SELECT clause, which then results in the JPQL giving an error.
The only way I know how to resolve this is to construct the query with separate query and countQuery values, like this:
#Query(query = """
SELECT p
FROM Person p
JOIN FETCH p.address
""", countQuery = """
SELECT COUNT(p)
FROM Person p
""")
Page<Person> getPeopleAndAddresses(Pageable page);
This resolves the JPQL JOIN FETCH error, because the count query no longer contains a JOIN FETCH clause. However, for complex queries with sophisticated JOINs and WHERE clauses, this will lead to excessive code duplication as I will have to write all that logic in two places.
This seems like the kind of issue where there really should be a better solution available. I'm exploring various alternatives, including Specifications (mixed feelings), Blaze Persistence, and others. However, I'm wondering if there is some way in Spring itself to resolve this issue so that the first code example would work without an error?
I have a springboot application that interacts with elastic search (or as it know now OpenSearch). It can perform basic operations such as search, index etc. I used this as my base (although I replaced high level client since it is deprecated) and to perform queries, I am using #Query annotation mostly (as described in section 2.2 here, although I also used QueryBuilders).
Now, I have an interesting use case - I would like to perform 2 queries at the same time. First query would find a file in elastic search that would contain 3 ids. These 3 ids are ids of other files in the same elastic search. The 2nd query would look for these 3 files and finally return them to me. Now, I can easily do it in 2 steps:
Have a query to find a file containing 3 ids and return it
Have a second query (multisearch query can do bulk search as I understand) to search
for 3 files using info from the first query.
However, I need them to happen within the same query - so within the same query I need to search for a file containing the 3 ids and then perform a search for these 3 files.
So currently my files in elastic search look like so:
{
"docId": "docId57",
"relatedDocs": [
{
"relatedId": "docId1",
"type": "apple"
},
{
"relatedId": "docId2",
"type": "orange"
},
{
"relatedId": "docId3",
"type": "banana"
}
]
}
and my goal is to have a query that will accept docId57 as an arg (so a method findFilesViaJoin(docId57) or something) and return a list of 3 files: file for docId1, file docId2 and file for docId3.
I know it is possible either via nested queries, child/parent queries or good old SQL queries (via jpa/hibarnate).
I attempted to use all of these and was unsuccessful for reasons described below.
Child/parent queries
So for child/parent queries, I attempted to use DSL with #Query but couldn't quite get it since I don't have a solid documentation to refer to (the one that actually helps with java not curls). After some time I found this and this articles - I maybe can figure out how to make it work with child/parent but neither explain how to do mapping. If this approach can do what I want, my question is: how to set up & map parent/child in springboot.
Using SQL queries
So for this one, I need to change my set up to use hibarnate. I used this as my base. It works, the only problem I have is that my SQL queries get ignored. Instead, the search is done based of a method's name, not the content of #Query. So it is as if I don't have an annotation used at all. So using the structure mentioned above, the following method in my app:
#Query("select t from MyModel t where t.docId = ?1")
findByRelatedDocsRelatedId(String id)
will return files that has a relatedId that matches the id passed via method ard id (as oppose to reading query from #Query that tells method to search all docs based on docId). Now, I don't mind using method name as a query to search for something. But then why would I use #Query for? (not to mention how do I create a name that does join). It might be possible that my hibernate is set up wrong (never used it before this week). So question here is, does anybody have a nice complete example of hibarnate being used with elastic search that does join query?
Nested queries
For these queries, I assume that I just need to figure out what to put inside the #Query but due to limited documentation about how to compose nested query I didn't manage to make it even remotely to work. Any concreate documentation on how to create DSL nested query would be appreciated.
Any of the ways I described will work for me. I think child/parent seems the best choice (seeing as they kind created for this purpose) but any will do.
I've been looking for some articles regarding this but havn't seen anyone have this issue. We are trying to reference a Virtual Field named "_ownerid_type". Expression: _ownerid_type eq 'systemusers' However it returns an error. I can see that the field is available in the Triggerbody and have performed similar filters with guids. Does anyone have any direction for me? Thanks in Advance.virtual field in Trigger output
OData Filter Expression
{ "error": {
"code": "0x80040203",
"message": "Exception parsing _ownerid_type eq 'systemusers' submitted for attribute filterexpression of callback registration.
Target entity: incident. Exception: Microsoft.OData.ODataException:
Could not find a property named '_ownerid_type' on type
'CallbackRegistration.incident'.\r\n at
Microsoft.OData.UriParser.EndPathBinder.GeneratePropertyAccessQueryForOpenType(EndPathToken
endPathToken, SingleValueNode parentNode)\r\n at
Microsoft.OData.UriParser.EndPathBinder.BindEndPath(EndPathToken
endPathToken)\r\n at
Microsoft.OData.UriParser.MetadataBinder.Bind(QueryToken token)\r\n
at
Microsoft.OData.UriParser.BinaryOperatorBinder.GetOperandFromToken(BinaryOperatorKind
operatorKind, QueryToken queryToken)\r\n at
Microsoft.OData.UriParser.BinaryOperatorBinder.BindBinaryOperator(BinaryOperatorToken
binaryOperatorToken)\r\n at
Microsoft.OData.UriParser.MetadataBinder.Bind(QueryToken token)\r\n
at Microsoft.OData.UriParser.FilterBinder.BindFilter(QueryToken
filter)\r\n at
Microsoft.OData.UriParser.ODataQueryOptionParser.ParseFilter()\r\n
at System.Web.OData.Query.FilterQueryOption.get_FilterClause()\r\n
at
Microsoft.Crm.ObjectModel.EdmModelEvaluator.EvaluateFilterExpression(String
filterExpression, ODataQueryOptions queryOptions)\r\n at
Microsoft.Crm.ObjectModel.EdmModelEvaluator.EvaluateFilterExpression(String
filterExpression)\r\n at
Microsoft.Crm.ObjectModel.CallbackRegistrationService.<>c.<.cctor>b__50_0(EdmModelEvaluator
evaluator, String testValue)\r\n at
Microsoft.Crm.ObjectModel.CallbackRegistrationService.ValidateInputEntity(IBusinessEntity
entity, ExecutionContext context, IFeatureDetailContainer
featureDetailContainer)" } }
Power Automate / Flow is returning that type property when a lookup is involved (for lookup here I mean standard and polymorphic lookup, owner and customer).
That property is not returned when executing a query against the Web API directly (I don't know if they are using some special annotations in order to retrieve it) but the #Microsoft.Dynamics.CRM.lookuplogicalname property contains the table name and in my opinion that should be checked, not the type one.
But you can't filter on these two properties (lookuplogicalname or type). Theoretically you can do a filter on the relationship column checking the id of the table, for example something like:
owninguser/systemuserid ne null
BUT Web API (more related to the OData implementation if I am correct) consider this kind of filter as Left Outer (not Inner Join) meaning it will return also rows where the records are actually owned by teams, making this kind of filter criteria useless (because you just want Cases owned by users if I understood correctly what you are doing).
As Alternative is to use a FetchXML query, but I am not aware of a way to execute a FetchXML query with the action you are using (the When a row is assigned to a user)
I know what I wrote is not a complete answer to your problem but it can give you some context on what is happening
I am using gorm to interact with a postgres database. I'm trying to ORDER BY a query that uses DISTINCT ON and this question documents how it's not that easy to do that. So I need to end up with a query in the form of
SELECT * FROM (<subquery>) ORDER BY column;
At first glance it looks like I need to use db.QueryExpr() to turn the query I have into an expression and build another query around it. However it doesn't seem gorm has an easy way to directly specify the FROM clause. I tried using db.Model(expr) or db.Table(fmt.Sprint(expr)) but Model seems to be completely ignored and fmt.Sprint(expr) doesn't return exactly what I thought. Expressions contain a few private variables. If I could turn the original query into a completely parsed string then I could use db.Table(query) but I'm not sure if I can generate the query as a string without running it.
If I have a fully built gorm query, how can I wrap it in another query to do the ORDER BY I'm trying to do?
If you want to write raw SQL (including one that has a SQL subquery) that will be executed and the results added to an object using gorm, you can use the .Raw() and .Scan() methods:
query := `
SELECT sub.*
FROM (<subquery>) sub
ORDER BY sub.column;`
db.Raw(query).Scan(&result)
You pass a pointer reference to an object to .Scan() that is structured like the resulting rows, very similarly to how you would use .First(). .Raw() can also have data added to the query using ? in the query and adding the values as comma separated inputs to the function:
query := `
SELECT sub.*
FROM (<subquery>) sub
WHERE
sub.column1 = ?
AND sub.column2 = ?
ORDER BY sub.column;`
db.Raw(query, val1, val2).Scan(&result)
For more information on how to use the SQL builder, .Raw(), and .Scan() take a look at the examples in the documentation: http://gorm.io/advanced.html#sql-builder
Hi Experts
I have a special question About dynamic Linq to Sql.
Consider we want to search in a table according two fields*(LetterNo(string) and LetterDate(Datetime))*
.OK the problem is user can enter on of that fields or even both.
I searched in the internet and found "Linq.Dynamic" library in ScottGu weblog.but in that library if we want to use SqlParameter in exported command we should use #0 and param for that.problem is I don't know how many fields user entered.
I want use one query for that and no external tool like "Linq Kit PredicateBuilder".
If I create my query string Manually(and execute using ExecuteCommand) then I will abdicate SqlParameter and risk of Sql Injenction growing up.
How Can do that?
thanks
I suspect you are wanting to do something like the following:
IQueryable<Letter> query = context.Letters;
if (!string.IsNullOrEmpty(LetterNo))
query = query.Where(letter => letter.LetterNo == LetterNo);
If (LetterDate.HasValue)
query = query.Where(letter => letter.LetterDate == LetterDate);
When you execute query, it will combine the necessary expressions and issue a single query to the database based on the user's input.