How to ignore null or empty values while using find() in Spring MongoRepository - spring-data-mongodb

I have a search functionality where there are different parameters and user can choose one or multiple parameters and ignore other parameters.
I want to use findByFirstNameAndLastNameAndAddressAndCountry() for this so that if any parameter is null or empty it can be ignored and the And condition get applied to other parameters

This can be a duplicate issue. You can do it using #Query annotation and your custom Query.
Ref: How to skip #Param in #Query if is null or empty in Spring Data JPA
#Query("select foo from Foo foo where foo.bar = :bar and "
+ "(:goo is null or foo.goo = :goo)")
public List<Foo> findByBarAndOptionalGoo(
#Param("bar") Bar bar,
#Param("goo") Optional<Goo> goo);

Use 'Query' and 'Criteria' option provided by Spring for MongoDB.
Query query = new Query();
if(!obj.getFirstName.isEmpty()){
Criteria criteria1 = Criteria.where('first_name').is(obj.getFirstName);
query.add(criteria1);
}

Related

Can i create a sql table populated with Salesforce objects?

does Salesforce offer a way to obtain all Objects like Account, Contact etc and populate them in a SQL table with certain columns like
ObjectEntity, FieldName , FieldType ?
I'm pretty sure the only way to achieve this would be by using the Schema.sObjectType and Schema.sObjectField. Here is a link to the documentation for getting all sObjects. You will basically call the Schema.getGlobalDescribe() method which will return you a map of sObjectTypes with their sObject name as the key. Then you'll need to call getDesribe() on each sObjectType get the fields of the object from that Describe result. You'll again need to call getDescribe() on each sObjectField in order to have access to the columns you wanted (eg. FieldType). Here is the documentation on that You could save each DescribeFieldResult into a list that goes into a Map of > with the sObject name as the key, then you could do what you want with them... Put them in a table if you like. Keep in mind this is all going to be very expensive when it comes to CPU time. You may even run into some governor limits.
Here is a little example you can run using Execute Anonymous in the developer console where the sObject Name and all its field names and types are printed to the debug logs
Map<String, sObjectType> objects = Schema.getGlobalDescribe();
for(String objName : objects.keySet()){
system.debug('=======' + objName + '=========\n Fields: ');
sObjectType o = objects.get(objName);
DescribeSobjectResult oDRes = o.getDescribe();
Map<String, Schema.SObjectField> fields = dResult.fields.getMap();
for(Schema.SObjectField f : fields.values()){
DescribeFieldResult fDRes = f.getDescribe();
system.debug('name: ' + fDRes.getName() + ' | type: ' + fDRes.getType());
}
}
Hope this helps

SQL XML parsing using a attribute value supplied by another field in the same row

Context: I'm scraping some XML form descriptions from a Web Services table in hopes of using that name to identify what the user has inputted as response. Since this description changes for each step (row) of the process and each product I want something that can evaluate dynamically.
What I tried: The following was quite useful but it returns a dynamic attribute query result in it's own field ans using a coalesce to reduce the results as one field would lead to it's own complications: Get values from XML tags with dynamically specified data fields
Current Attempt:
I'm using the following code to generate the attribute name that I will use in the next step to query the attribute's value:
case when left([Return], 5) = '<?xml'
then lower(cast([Return] as xml).value('(/response/form/*/#name)[1]','varchar(30)'))
else ''
end as [FormRequest]
And as part of step 2 I have used the STUFF function to try and make the row-level query possible
case when len(FormRequest)>0
then stuff( ',' + 'cast([tmpFormResponse] as xml).value(''(/wrapper/#' + [FormRequest] + ')[1]'',''varchar(max)'')', 1, 1, '')
else ''
end as [FormResponse]
Instead of seeing 1 returned as my FormReponse feild value for the submit attribute (please see in yellow below) it's returning the query text -- cast([tmpFormResponse] as xml).value('(/wrapper/#submit)1','varchar(max)') -- instead (that which should be queried).
How should I action the value method so that I can dynamically strip out the response per row of XML data in tmpFormResponse based on the field value in the FormRequest field?
Thanx
You can check this out:
DECLARE #xml XML=
N'<root>
<SomeAttributes a="a" b="b" c="c"/>
<SomeAttributes a="aa" b="bb" c="cc"/>
</root>';
DECLARE #localName NVARCHAR(100)='b';
SELECT sa.value(N'(./#*[local-name()=sql:variable("#localName")])[1]','nvarchar(max)')
FROM #xml.nodes(N'/root/SomeAttributes') AS A(sa)
Ended up hacking up a solution to the problem by using PATINDEX and CHARINDEX to look for the value in the [FormRequest] field in the he tmpFormResponse field.

Using wildcards for column names in dynamic soql in apex

I have a scenario where my columns names can be of type genesis__prod__c/docgen__prod__c/lnd__prod__c,etc depending upon which package is using my solution package. Here genesis,docgen and are different product packages using my solution.
My solution needs to fetch any of these(genesis__prod__c/docgen__prod__c/lnd__prod__c) fields from there respective sObjects in there products.
I want to construct a generic query which will omit the namespace using a wildcard and only look for prod__c in specified sObject. With this, I don't have to hardcode any namespace in my query.
for eg., I don't want to form my query like this
String query = 'select Id,Name,docgen__CL_Product__c from '+ sObjectType + ' where id= \'' + appId + '\'';
List<sObject> runtimeDeterminedObject = Database.query(query+' LIMIT 1');
Here I have specifically mentioned docgen__CL_Product__c name to be fetched from a runtime resolved sObject name sObjectType w.r.t an appId
How can I form a query where I do not have to provide namespace docgen,genesis before prod__c. I do not want to write if-else for each product which can utilize my package.
Why don't you make the namespace a variable that gets appended to the query based on some condition? Not exactly what you're looking for, but I'm assuming there's some way to determine the environment and then based on that you can adjust the query dynamically:
String env = someCondition ? 'genesis__' : 'docgen__';
String query = 'select Id, Name, ' + env + 'CL_Product__c from '+ sObjectType + ' where id= \'' + appId + '\'';
List<sObject> runtimeDeterminedObject = Database.query(query+' LIMIT 1');

UPDATE only a part of a string value in a column

I am new to t-sql. I have a column which stores values as url's. I want to change the first part of the url's (string), and replace only this part with another url. For example, [url//lsansps01/PMO/ITG0038 iSCOMBI Data Model Project] to [url2//lwazitest.lionsure.com/PMO/ITG0038 iSCOMBI Data Model Project]
This is my update query:
UPDATE dbo.RowUpdates
SET ProjectWorkspaceInternalHRef = REPLACE ProjectWorkspaceInternalHRef, url//lsansps01/, url2//lwazitest.lionsure.com/PMO/ITG0038 iSCOMBI Data Model Project
FROM RowUpdates
WHERE ProjectWorkspaceInternalHRef LIKE url
REPLACE uses () and not comma delimited parameters,
UPDATE dbo.RowUpdates
SET ProjectWorkspaceInternalHRef = REPLACE(ProjectWorkspaceInternalHRef, 'url//lsansps01/', 'url2//lwazitest.lionsure.com/PMO/ITG0038 iSCOMBI Data Model Project')
FROM RowUpdates
WHERE ProjectWorkspaceInternalHRef LIKE url
another questionable part is LIKE url for it to work there should be '%'+url+'%' or something similar.
You want to look at MSDN: REPLACE (Transact-SQL)
from the article:
REPLACE ( string_expression , string_pattern , string_replacement )
so you'd want to change your replace statement to (remember to use a quote (') around your strings):
UPDATE dbo.RowUpdates
SET ProjectWorkspaceInternalHRef =
REPLACE(ProjectWorkspaceInternalHRef, 'url//lsansps01/', 'url2//lwazitest.lionsure.com/PMO/ITG0038 iSCOMBI Data Model Project')
FROM RowUpdates
WHERE ProjectWorkspaceInternalHRef LIKE url
It's also worth looking at the list of String Functions (Transact-SQL) you get in SQL Server.
Replace() function will not give your expected results if #OldUrl text is found in the middle of the ProjectWorkspaceInternalHRef.
If you want to replace only the front bit, use RIGHT() (or SUBSTRING()) function after filtering them out with LEFT() function.
DECLARE #OldUrl VARCHAR(500) = 'YourOdlUrl',
#NewUrl VARCHAR(500) = 'YourNewUrl'
UPDATE dbo.RowUpdates
SET ProjectWorkspaceInternalHRef = #NewUrl +
RIGHT(ProjectWorkspaceInternalHRef, LEN(ProjectWorkspaceInternalHRef) - LEN(#OldUrl ))
WHERE LEFT(ProjectWorkspaceInternalHRef, LEN(#OldUrl )) = #OldUrl

Salesforce SOQL describe table

Is there a way to fetch a list of all fields in a table in Salesforce? DESCRIBE myTable doesn't work, and SELECT * FROM myTable doesn't work.
From within Apex, you can get this by running the following Apex code snippet. If your table/object is named MyObject__c, then this will give you a Set of the API names of all fields on that object that you have access to (this is important --- even as a System Administrator, if certain fields on your table/object are not visible through Field Level Security to you, they will not show up here):
// Get a map of all fields available to you on the MyObject__c table/object
// keyed by the API name of each field
Map<String,Schema.SObjectField> myObjectFields
= MyObject__c.SObjectType.getDescribe().fields.getMap();
// Get a Set of the field names
Set<String> myObjectFieldAPINames = myObjectFields.keyset();
// Print out the names to the debug log
String allFields = 'ALL ACCESSIBLE FIELDS on MyObject__c:\n\n';
for (String s : myObjectFieldAPINames) {
allFields += s + '\n';
}
System.debug(allFields);
To finish this off, and achieve SELECT * FROM MYTABLE functionality, you would need to construct a dynamic SOQL query using these fields:
List<String> fieldsList = new List<String>(myObjectFieldAPINames);
String query = 'SELECT ';
// Add in all but the last field, comma-separated
for (Integer i = 0; i < fieldsList.size()-1; i++) {
query += fieldsList + ',';
}
// Add in the final field
query += fieldsList[fieldsList.size()-1];
// Complete the query
query += ' FROM MyCustomObject__c';
// Perform the query (perform the SELECT *)
List<SObject> results = Database.query(query);
the describeSObject API call returns all the metadata about a given object/table including its fields. Its available in the SOAP, REST & Apex APIs.
Try using Schema.FieldSet
Schema.DescribeSObjectResult d = Account.sObjectType.getDescribe();
Map<String, Schema.FieldSet> FsMap = d.fieldSets.getMap();
complete documentation
Have you tried DESC myTable?
For me it works fine, it's also in the underlying tips in italic. Look:

Resources