I am implementing full text search on Jackrabbit Repository. After going through the examples given at http://jackrabbit.apache.org/ocm-search.html, I am able to write perform full text search on repository when only 'and' is required in the predicate. For example:
select * from test where name like '%abc%' and type = 'mainPage' and language = 'english'
can be written as
Filter filter = queryManager.createFilter(Paragraph.class);
filter.addContains('name', 'abc');
filter.addEqualTo('type', 'mainPage');
filter.addEqualTo('language ', 'english');
But, if I try to write the OCM implementation for the following query
select * from test where (name like '%abc%' or name like '%def%' ) and type = 'mainPage' and language = 'english'
as given bellow, I am getting empty list
Filter mainFilter= queryManager.createFilter(Paragraph.class);
Filter filter = queryManager.createFilter(Paragraph.class);
filter.addContains('name', 'abc');
Filter filter1 = queryManager.createFilter(Paragraph.class);
filter.addContains('name', 'def');
mainFilter = filter .addOrFilter(filter1 );
mainFilter .addEqualTo('type', 'mainPage');
mainFilter .addEqualTo('language ', 'english');
I think I am not able to use OCM full text search properly. Please suggest me the right way to implement OCM full text search in which predicate contains a large number of 'and' and 'or' conditions.
When I used
filter.addLike('name','%def%');
It's working fine. I am still wondering why addContains() is not working.
Related
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.
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
I've been struggling with implementing this. I'm trying to build a dynamic queryset where the conditions will be based on user entry. A user can decide to search by first or last name or a combination of both. If searching by only last name the firstname query will not be added to the queryset. I currently have it working for a search with all the fields entered.
results = documents.objects.filter(
Q(f_filer__filer_first_name__istartswith=request.GET.get('first_name',
'')) & (f_filer__filer_last_name__istartswith=request.GET.get('last_name',
'')) &
Q(f_office__o_office_name__istartswith=request.GET.get('office_name', ''))
& Q(f_doc_year__exact=request.GET.get('report_year', ''))
& Q(f_report_id__exact=request.GET.get('filing_type', ''))
).values('f_filer__filer_first_name',
'f_filer__filer_last_name',
'f_office__o_office_name',
'f_date_received',
'f_start_travel_date',
'f_end_travel_date',
'f_doc_year',
'f_report__r_title')
You can just concatenate filter like this:
queryset = documents.objects.all()
first_name = request.GET.get('first_name')
last_name = request.GET.get('last_name')
if first_name:
queryset = queryset.filter(first_name=first_name)
if last_name:
queryset = queryset.filter(last_name=lastname)
I have shorten the filter arguments for simplifying the example
You can join Q objects using |, which acts as an "or":
first_name = request.GET.get('first_name', '')
last_name = request.GET.get('last_name', '')
Q(
f_filer__filer_first_name__istartswith=first_name,
f_filer__filer_last_name__istartswith=last_name
) |
Q(f_filer__filer_first_name__istartswith=first_name) |
Q(f_filer__filer_last_name__istartswith=last_name)
If your application is search-heavy, it might be worth looking into setting up a proper search backend.
Do you use Postgres? If so, using Django's Postgres Full text search would probably simplify things and help make the code more maintainable.
If you don't use Postgres, setting up a search backend with django-haystack would give you similar benefits and allow users to construct Google-like queries using AutoQuery. For example, using - to exclude a term and quotes for an exact phrase.
İ have a problem with contains function, when i search with like '%ZAM%' operator, it finds all word that contains ZAM like ZAMANLAMA AZAMI ZAM and etc.. but when I use fts index contains function, it just find ZAM ZAMANLAMA but it doesnt find AZAMI or 123ZAM789. I have also tried CONTAINS (YourColumn, ' "ZAM" ' ) but it doesn't work. Please help me , fts is very fast but it could not find all contains like '%%' operator what should I do ?
You can use "*" before in contain syntax same as like operator . but you need to use double quote before and after the search string.
Try this query once.
SELECT *
FROM YourTable
WHERE CONTAINS(YourColumn,'"*ZAM*"');
(OR)
select * from YourTable where YourColumn like '%ZAM%'
replacing XML tag value within a large XML text value MSSQL.
Within MSSQL I have a column called form which is a text column with an extremely large XML. I need to find a certain tag and change the value of that sub tag within the tag from False to True.
This is what I currently have:
USE trainset;
UPDATE dbo.users
SET formxml = REPLACE(CAST(formxml as nvarchar(max)), '%<ttaycheckbox><name>cbTermsConditions</name><cargo>F</cargo></ttaycheckbox>%', '<ttaycheckbox><name>cbTermsConditions</name><cargo>T</cargo></ttaycheckbox>')
WHERE usersid = '0000GARX'
and formname ='ffOrderRpt'
and formxml LIKE ('%<ttaycheckbox><name>cbTermsConditions</name><cargo>F</cargo></ttaycheckbox>%')
It seems like it is doing the update;
However, after this when I do a select on this particular value the value of is still False rather than True.
What am I missing in there that is not causing it to update properly?
replace() doesn't support wildcards. So your where ... like finds the relevant records, but replace finds NOTHING, because it's looking for a literal %.
You can use XML modify and exist:
UPDATE users
SET formxml.modify('replace value of (/ttaycheckbox/cargo/text())[1] with "T"')
WHERE usersid = '0000GARX'
and formname ='ffOrderRpt'
and formxml.exist('/ttaycheckbox/name[text()[1] eq "cbTermsConditions"]') = 1
and formxml.exist('/ttaycheckbox/cargo[text()[1] eq "F"]') = 1