Spring+Cassandra+Solr Grouping - solr

Is it possible to grouping data more than one field by using SolrTemplate
example, i want to group by id and name in a table

As the group options returns a list of group by fields you can probably do something like this:
Query query = new SimpleQuery(new SimpleStringCriteria("*:*"));
SimpleQuery groupQuery = new SimpleQuery(new SimpleStringCriteria("*:*"));
GroupOptions groupOptions = new GroupOptions()
.addGroupByField("id")
.addGroupByField("name")
.addGroupByQuery(query);
groupQuery.setGroupOptions(groupOptions);
GroupPage<Foo> page = solrTemplate.queryForGroupPage(query, Foo.class);
Read more in the docs here.

Related

Dapper, SqlBuilder extension and Order By descending

I am trying to build a simple query that retrieves data in descending order using Dapper. The database is MySql if that's important.
This is the code I used:
var builder = new SqlBuilder();
var sql = #$"SELECT * FROM table t /**orderby**/ LIMIT #paramSkip, #paramTake";
var template = builder.AddTemplate(sql);
builder.OrderBy("#paramOrderBy DESC", parameters: new
{
paramOrderBy = orderBy,
});
// Limit
builder.AddParameters(parameters: new
{
paramSkip = skip,
paramTake = take
});
return Connection.QueryAsync<TableModel>(
template.RawSql, template.Parameters,
transaction: Transaction
);
This always returns data in ascending order. DESC is just ignored. I tried using the DESC keyword in the query or as parameter but the result was the same.
Only thing that worked was putting order parameters and DESC keyword in query itself (by string interpolation)
(Edit: Typos and text simplification)
You need your query to look something like this:
... ORDER BY <Column name> DESC ...
A column name cannot be parameterized, so you need to insert it into the query something like this:
builder.OrderBy($"{orderBy} DESC");
If your orderBy originates from the user in any way, be sure to sanitize it first to prevent SQL injection. You could - for instance - keep a list of valid column names and validate against it.

How to select columns with other name in linq?

I select my records in SQL Server Query as you seen below:
SELECT ProductName 'Some Name1' ,
Payment 'Some Name2'
FROM dbo.PrefactorProduct
Is there a way to select records like that in linq queries?
You can project result from your query to an Anonymous type and use different alias/field names for your fields.
var query = db.PrefactorProduct
.Select(r=> new
{
SomeName1 = r.ProductName,
SomeName2 = r.Payment
});
But if you are trying to format your result set for displaying purpose then you should look in to assigning column names for your grid/ data container.

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:

How to get array of row values from JDBC result set

I have a sql statement that brings back the following rows:
I would like to obtain these values from a JDBC result set as two objects. One for the customer with customerNo 1 and the other for customer 2. I would like the two objects to have another array value with the related Titles with the object values.
The structure would ultimately look like this (in JSON):
{customerNo : 1, ["Object 1", "Object 2", "Object 3"]}, {customerNo : 2, ["Object 4", "Object 5"]}
How can I accomplish this with JDBC?
You can use a Map to initially collect the results in the format you want.
Map<Integer, Set<String>> customerTitles = new HashMap<Integer, Set<String>>();
while(resultSet.next()) {
Integer custId = resultSet.getInt(1);
Set<String> titles = customerTitles.containsKey(custId) ?
customerTitles.get(custId) : new HashSet<String>();
titles.add(resultSet.getString(2));
customerTitles.put(custId, titles);
}
Once you have it collected this way, you can iterate over the Map and in turn the Sets within and convert them to JSON
// Convert to Json array here using your JSON library
for(Integer custId : customerTitles.keySet()) {
for(String title : customerTitles.get(custId)) {
}
}
Two ways that I can think of.
Get the CustomerNo first with a SELECT DISTINCT query and keep it in a COLLECTION.
Then for every (using a loop) CustomerNo in the COLLECTION perform a SELECT Title from table WHERE CustomerNo = <collectionValue> and create a new JSON Object for each CustomerNo.
Fetch the RESULTSET with a SELECT CustomerNo, Title FROM tablename ORDER BY CustomerNo.
In the fetching code (inside the loop) of the RESULTSET assign a variable to the CustomerNo you are getting from the RESULTSET and check for the next row. If you encounter a new CustomerNo then create a new JSON Object.

How to access Ambiguous Column in SQL Query with SELECT *

When I execute Stored Procedure
SELECT * FROM Users
INNER JOIN BloodBankUser ON Users.UserID = BloodBankUser.UserID
It gives me result fine.
but now on .net side
dt.Rows[0]["Address"].ToString();
this gives me Address of table BloodBankUser
dt.Rows[0]["Users.Address"].ToString();
when I debug this statement it execute error
Column 'Users.Address' does not
belong to table.
How can I get Value of Users.Address
While the first answer would be to change your SQL Query to specify a distinct name for each of your field, it is still possible to retrieve the table name associated with your field.
In this example, I am not filling a DataTable using a DataAdapter, but rather I am using the SqlDataReader.
Be aware that this may fail if you are unable to retrieve the database schema for any reason
When calling ExecuteReader on a SqlCommand, there is an overload that allows you to specify a CommandBehavior. In our case, the behavior that we want is CommandBehavior.KeyInfo.
var reader = command.ExecuteReader(CommandBehavior.KeyInfo);
Now, on the reader, you can invoke the GetSchemaTable method. It returns a DataTable that contains the structure of your query.
var schema = reader.GetSchemaTable();
You can read about that table on MSDN.
Our goal now is to match the field and table against its ordinal position in the column list. Three fields from the schema table are relevant to your interest:
ColumnName
BaseTableName
ColumnOrdinal
You can then create an extension method to do that reading:
public static T Field<T>(this SqlDataReader reader, DataTable schema, string table, string field)
{
// Search for the ordinal that match the table and field name
var row = schema.AsEnumerable().FirstOrDefault(r => r.Field<string>("BaseTableName") == table && r.Field<string>("ColumnName") == field);
var ordinal = row.Field<int>("ColumnOrdinal");
return (T)reader.GetValue(ordinal);
}
You can then call that extension method
using (SqlConnection connection = new SqlConnection("your connection string"))
{
connection.Open();
using (SqlCommand command = new SqlCommand("SELECT * FROM Users INNER JOIN BloodBankUser ON Users.UserID = BloodBankUser.UserID;", connection))
using (var reader = command.ExecuteReader(CommandBehavior.KeyInfo))
{
var schema = reader.GetSchemaTable();
while (reader.Read())
{
Console.WriteLine(reader.Field<string>(schema, "Users", "Address"));
}
}
}
Rename the FIELD in the output (Select FIELDNAME as NEWNAME)
You specify the column names rather than use SELECT * FROM You will then be able to do the following
Select User.Username,
User.Address as 'UserAddress',
BloodBankUser.Address as 'BloodbankAddress'
FROM Users
INNER JOIN BloodBankUser ON Users.UserID = BloodBankUser.UserID
Avoid the use of * in SELECT queries. Select only the columns you need and name them explicitly to avoid ambiguity,
Insead of SELECT *... specify the columns you want explicitly, and alias those that may duplicate
SELECT Users.Address as UsersAddress

Resources