Add Custom SObject to List of SObjects in Apex Controller - salesforce

I have a custom Apex controller where I have an SOQL query that gets a count of all objects that have a certain status and that are children of another object. The query is:
List<SObject> statuses = [SELECT Status__c, COUNT(Id) statusCount FROM Application__c WHERE CERT__c = :certId GROUP BY Status__c];
Status__c is a Picklist. I also have code to get all of the possible values of the Picklist.
What I want to do is if statuses does not contain any entries that have a specific Status__c value, to add the value name with a count of 0. For some reason when I try to create a new SObject with a Status__c and Count, it doesn't seem to like it. Is there a way to add a custom SObject to the list? Or, should I be handling this differently?

I was very surprised that your query works. Result of queries with GROUP BY is AggregateResult, I didn't know it can be cast down to sObject. Maybe initial success with this made you fail in the next steps...
Something like this should point you in right direction:
Map<String, Integer> results = new Map<String, Integer>();
for(Schema.PicklistEntry pe : Lead.LeadSource.getDescribe().getPicklistValues()){
results.put(pe.getValue(), 0);
}
System.debug('Before: ' + JSON.serializePretty(results));
for(AggregateResult ar : [SELECT LeadSource, COUNT(Id) cnt FROM Lead WHERE LeadSource != null GROUP BY LeadSource]){
results.put((String) ar.get('LeadSource'), (Integer) ar.get('cnt'));
}
System.debug('After: ' + JSON.serializePretty(results));
Before: {
"Some more types" : 0,
"Hi Stackoverflow!" : 0,
"Other" : 0,
"Purchased List" : 0,
"Partner Referral" : 0,
"Phone Inquiry" : 0,
"Web" : 0
}
After: {
"Some more types" : 0,
"Hi Stackoverflow!" : 0,
"Other" : 0,
"Purchased List" : 7,
"Partner Referral" : 4,
"Phone Inquiry" : 4,
"Web" : 7
}

Related

Salesforce, Apex, SOQL, SELECT with INCLUDES

What is wrong at this code in Apex?
String states = 'California,New York';
List<Account> lstACC = [SELECT Id, Name, BillingState FROM Account WHERE BillingState INCLUDES (:states) LIMIT 10];
In Developer Console is an Error: "BillingState FROM Account WHERE BillingState INCLUDES (:states)^ERROR at Row:1:Column:50 includes or excludes operator only valid on multipicklist field".
The text of the error shows the problem:
includes or excludes operator only valid on multipicklist field
BillingState is not a multi-select picklist. Use IN rather than INCLUDES to match against the collection.
Note additionally that a comma-separated string is not a valid collection to match against. Create a List<String> or Set<String> to use in your matching condition.
The right solution:
Set<String> setStates = new Set<String>();
setStates.add('California');
setStates.add('New York');
List<Account> lstACC = [SELECT Id, Name, BillingState
FROM Account
WHERE BillingState IN :setStates
LIMIT 10];
Wrong:
setStates: {'California','New York'}
Right:
setStates: {California,New York}
Apostrophes are in addition.
OR
String states = 'California,New York';
List<String> listStates = states.split(',');
List<Account> lstACC = [SELECT Id, Name, BillingState
FROM Account
WHERE BillingState IN :listStates
LIMIT 10];
Wrong:
String states = '\'California\',\'New York\'';
Right:
String states = 'California,New York';
SOQL injection is in addition.

MongoDB aggregate sorting different response on same values

when i was pagination with mongodb aggregation, i found a problem. I'll detail this a little bit. This problem only happens when sorting. I made a pattern to keep it simple.
Model have a count (number) random generated for sorting and have id (number) for so that we can do it visually and it is unique.
Aggregate pipeline like
db.getCollection('test').aggregate([{
$sort:{
count:-1
}
},
{
$skip : 0
},
{
$limit :2
}])
Example limit 2
Returned data
/* 1 */
{
"_id" : ObjectId("6027005ffba493078dca3580"),
"count" : 9,
"id" : 38
}
/* 2 */
{
"_id" : ObjectId("6027005ffba493078dca3565"),
"count" : 9,
"id" : 11
}
When limit example 3
Returned data
/* 1 */
{
"_id" : ObjectId("6027005ffba493078dca3587"),
"count" : 9,
"id" : 45
}
/* 2 */
{
"_id" : ObjectId("6027005ffba493078dca3580"),
"count" : 9,
"id" : 38
}
/* 3 */
{
"_id" : ObjectId("6027005ffba493078dca3565"),
"count" : 9,
"id" : 11
}
For limit 2 first element id = 38,
For limit 3 first element id = 45
And its returned always different response for different limit skip value, for same value sorting.
This problem is preventing me from pagination properly.
If I add a second sorting example
$sort:{
count:-1
_id: 1
}
}
Its a resolved.
What is the reason? and another solution?
This is expected behavior when document with id:45 is inserted immediately after the limit:2 aggregation example was executed , the limit:3 example will show you the document with id:45 on the top place since the documents/indexes are loaded for sorting based on the natural insertion order by document _id and the _id is monotonically increasing already sorted.
Based on the above I don't think it make any difference if you add also the _id in the sort stage since documents will be automatically sorted based on the _id if it is not specified and the count value is same for all documents ...

Mongodb find() query returns nothing while field and value exists

I have this simple database with one single collection and when I try a simple query with a field and value that exists il returns nothing.
one row of the database :
{
"title" : "Cupone Salice Salentino",
"sku" : 1000126,
"vendor" : "messapia-tesori-del-salento",
"image" : "",
"estimatedprice" : 21,
"finalprice" : 21,
"qty" : 1,
"category" : "Vins & alcools",
"status" : "fulfilled"
}
Code:
db.orders.find(); // this works
db.orders.find({qty : 2}); // this returns nothing
I think you have not gave whole document here.Because according to me "qty" is in array in your document object that's why.

Array key names start with specific name in mongodb

How to get key names from array in a collection which is start from specific name;
var regExp=/specific name of key/
var cur = db.collectionName.find();
cur.forEach(function(doc)
{{ Object.keys(doc).forEach(function(key)
{return key.match(regExp)})}}
var allKeys = {};
var regExp=/Alar/
db.collectionName.find().forEach(function(doc){Object.keys(doc).forEach(function(key){allKeys[key]=1})});
allKeys;
with above code output ;
{
"_id" : 1,
"id" : 1,
"type" : 1,
"Name" : 1,
"device_type" : 1,
"grammerData" : 1,
"code" : 1,
"Command" : 1,
"description" : 1,
"created_by" : 1,
"last_updated_time" : 1
}
now i want some script from which i can find those keys which start with specific name.
Its not working properly ,please help me out?
You can perform regex search in mongodb like the following:
db.collectionname.find({field:/abc/},function(err,data) {
//your code
}
This will search for all the documents that starts with abc. If you wanna search from more than one regex, you can use the $in operator to search for values inside an array:
db.collectionName.find({field:{$in:[/abc/,/what/]}},function(err,data){
//your code
}
This will return all the documents in which the field "field" starts with abc or what
Hope my answer was helpful.

findBy query not returning correct page info

I have a Person collection that is made up of the following structure
{
"_id" : ObjectId("54ddd6795218e7964fa9086c"),
"_class" : "uk.gov.gsi.hmpo.belt.domain.person.Person",
"imagesMatch" : true,
"matchResult" : {
"_id" : null,
"score" : 1234,
"matchStatus" : "matched",
"confirmedMatchStatus" : "notChecked"
},
"earlierImage" : DBRef("image", ObjectId("54ddd6795218e7964fa9086b")),
"laterImage" : DBRef("image", ObjectId("54ddd67a5218e7964fa908a9")),
"tag" : DBRef("tag", ObjectId("54ddd6795218e7964fa90842"))
}
Notice that the "tag" is a DBRef.
I've got a Spring Data finder that looks like the following:
Page<Person> findByMatchResultNotNullAndTagId(#Param("tagId") String tagId, Pageable page);
When this code is executed the find query looks like the following:
{ matchResult: { $ne: null }, tag: { $ref: "tag", $id: ObjectId('54ddd6795218e7964fa90842') } } sort: {} projection: {} skip: 0 limit: 1
Which is fine, I get a collection of 1 person back (limit=1). However the page details are not correct. I have 31 persons in the collection so I should have 31 pages. What I get is the following:
"page" : {
"size" : 1,
"totalElements" : 0,
"totalPages" : 0,
"number" : 0
}
The count query looks like the following:
{ count: "person", query: { matchResult: { $ne: null }, tag.id: "54ddd6795218e7964fa90842" } }
That tag.id doesn't look correct to me compared with the equivalent find query above.
I've found that if I add a new method to org.springframework.data.mongodb.core.MongoOperations:
public interface MongoOperations {
public long count(Query query, Class<?> entityClass, String collectionName);
}
And then re-jig AbstractMongoQuery.execute(Query query) to use that method instead of the similar method without the entityClass parameter then I get the correct paging results.
Question: Am I doing something wrong or is this a bug in Spring Data Mongo?
Edit
Taking inspiration from Christoph I've added the following test code on Git https://github.com/tedp/Spring-Data-Test
The information contained in the Page returned depends on the query executed. Assuming a total number of 31 elements in you collection, only a few of them, or even just one might match the given criteria by referencing the tag with id: 54ddd6795218e7964fa90842. Therefore you only get the total elements that match the query, and not the total elements within your collection.
This bug was actually fixed DATAMONGO-1120 as pointed out by Christoph. I needed to override the spring data version to use 1.6.2.RELEASE until the next iteration of Spring Boot where presumably Spring Data will be up lifted to at least 1.6.2.RELEASE.

Resources