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
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.
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 ...
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.
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.
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.