Does ##parentid attribute work in Sitecore query? - sitecore

Sitecore reference talk about some attributes you can use in Query, including ##templatename, ##id and ##parentid etc.
parentid doesn't seem to work - /sitecore/content//*[##parentid!=''] never returns any result. While /sitecore/content//*[##templatename!=''] works fine. Sitecore version is 6.5 and 6.6.
Has anyone been able to query with ##parentid? ( Perhaps it uses Ancestor/Descendant table and I'm missing data?? - just a guess )

It is attempting to parse the value as a GUID and failing. Instead, try an empty GUID like so:
/sitecore/content//*[##parentid!='{00000000-0000-0000-0000-000000000000}']

##parentid only works in fast query.
In fast query you can only use ancestor not ancestor-or-self (which doesn't give an error it just does a fallback too ancestor).
Also you can't use the pipe | in fast query to concatenate results of 2 or more queries.
I can't for the life of me figure out how to do a "give me the ancestor-or-self of the current node whose parent has id={110D559F-DEA5-42EA-9C1C-8A5DF7E70EF9}.

Related

Drupal 8: Altering Search API queries

I'm working on a project which includes the following activated modules:
Drupal core 8.2.3
Database Search 8.x-1.0-beta4
Search API 8.x-1.0-beta4
Search API Term Handlers 8.x-1.0-beta4
Views 8.2.3
I have a list of nids which need to be excluded from the search result of the site-wide search. The search uses Search API and has been setup using Views.
The table in the database is: "search_api_db_default_index"
The field I wish to target is: "nid"
I wasn't able to get HOOK__search_api_query_alter or HOOK_search_api_results_alter to fire, so I am attempting to manipulate the query through HOOK_views_query_alter.
I have attempted to use both the "addWhere" and "addCondition" methods with the following syntax:
When using the addCondition method, I attempted
$query->addCondition('search_api_db_default_index.nid', $oneBadNid, '<>');
and
$query->addCondition('search_api_db_default_index.nid', $manyBadNids, 'NOT IN');
and when using the addWhere method, I attempted
$query->addWhere('AND', 'search_api_index_default_index.nid', $oneBadNid, '<>');
and
$query->addWhere('AND', 'search_api_index_default_index.nid', $manyBadNids, 'NOT IN');
Regardless of whether or not I prefix the field with the table name, searching always results in triggering the following notice:
Unknown field in filter clause: 'search_api_db_default_index.nid' .
It seems that the field name is always wrapped in an html encoded string representing a single quotation, but this occurs both when using double quotations or single quotations around the supplied table.field parameter.
I am not even sure that this is what is keeping me from altering my query, but it is the only thing close to an error which I have discovered in this process. It's also possible that I'm simply not supposed to be targeting the table in the manner written, but I did not find any documentation directing me to the proper methodology.
I would appreciate any insight into this issue! Thanks!
Generally you can use
$fields = $query->getIndex()->getFields();
on the query to get an array of fields you can use within the search_api query.
Piggy-backing off of Nebel54's comment, and attempting this on my own, you don't need to include the 'table' name when setting the addCondition. However, I did need to use hook_search_api_query_alter over a views-specific one.
function mymodule_search_api_query_alter(\Drupal\search_api\Query\QueryInterface &$query) {
// Ensure field_myfield is being indexed
$fields = $query->getIndex()->getFields();
if (isset($fields['field_myfield'])) {
$query->addCondition('field_myfield', 'myvalue', '<>');
}
}

Sitecore Fast Query Get Descendants Query Syntax Inconsistent

I came across an old project previously written for Sitecore 6.4 and now updated to Sitecore 7.2.
There is a fast query that does not return results:
1. fast:/sitecore/content/Home/About Us/News//*[##templatename='Newsletter']
I tried to tweak the query and these two are working fine:
2. fast:/sitecore/content/Home/About Us/News/descendant::*[##templatename='Newsletter']
3. fast:/sitecore/content/Home/About Us/News/Newsletters//*[##templatename='Newsletter']
The Newsletter items are not direct children of Newsletters item either, there is another layer in between.
So Why the query 1 does not work while 2 & 3 return exactly what I need?
Check your web.config setting for FastQueryDescendantsDisabled.
Rebuild your Descendents table via Control Panel, Databases, Clean Up Databases
Reference: http://sdn.sitecore.net/upload/sdn5/developer/using%20sitecore%20fast%20query/using%20sitecore%20fast%20query001.pdf
Check to see if the number of descendants of "News" is under whatever the maximum returned items size is set to in the web config (<setting name="Query.MaxItems" value="100" />).
While you aren't returning items while looking at the descendants, it is possible that the older version of Sitecore only looks at the max number of items (which would be a bug). The fact that query 3 works and query 1 doesn't is says to me that this is likely the issue. Query 2 is trying to do the same thing, but queries 1 and 3 also happen to be the same syntax. Since all three are meant to do the exact same thing (the only exception being that /News/Newsletters is looking from deeper root item), I would expect that this is a bug.
You can test this by setting the value of the Query.MaxItems setting to a ridiculously high number, like 5000 (note that you should change the value back after testing, as this can greatly degrade performance). If query 1 now returns items, then this is your issue. Otherwise, try setting the value higher. If it still doesn't return values after that, then this is not your issue.
Let me know if you have any questions. Good luck and happy coding! :)

Usage of Id='' in EAI Siebel Adapter Query

Requirement: I am suppose to use an existing Integration Object for my requirement. As this IO consists of ICs that I do not need in my requirement, I would like to avoid them in my IO query output.
I observe that passing Id = '' returns no result in Siebel 8.0. Can I use it as a feature and pass SearchSpec => [Integration Component.Id]='' to EAI Siebel Adapter query to suppress ICs that I don't want in output?
How good is this query Id=''? Will Siebel ignore this query completely? or will it attempt and return no output?
As per my understanding Siebel ignores the query where row_id is passed as ''
(Not true for siebel 6.0) Please share your opinion.
Not sure of using Id = '', when you club the condition with other conditions, Siebel might try to find actual matching records. Also , not sure if future upgrading will keep the same system.
If yours is the only code using the IO, you could straightaway inactivate the ICs you dont want.
If you are unsure of IC inactivation, best way should be to a DatMapper. Set up an EAI Datamapper, source and target IOs of same name. In this datamapper, map only the ICs you need. After querying from EAI Siebel Adapter, send your output to this DataMapper.
Siebel will keep only the ICs mapped and remove all the rest.
Since this is a non-repository change, you can modify the DataMapper in future too.
Hope this helps !
Answering it myself with my opinion..
As per my understanding, querying with Id='' still queries the database for row_id = ''. Including this in IO query reduces the query scope to the parent's context..
Though this won't improve any performance, IO query output looks cleaner.
Update: I'm using a Indexed column based field Id (ROW_ID) with search spec as "[Id] IS NULL". It's a next to impossible case in database having ROW_ID = NULL, unless it's intentionally and manually updated. Again no one would do it unless really wants to messup that data .. because without ROW_ID record is literally invalid..
Adding a null query to the IC will inherently result in an empty property set for the IC in question. But if you don't need the IC, and the ICs in the IO are not hierarchically connected (no hierarchy key )(eg- independant BCs with same base table in the same BO), you just have to remove the IC mapping in the datamap editor and the IC wont show in the IO propset

Group by date field in solrj

i want to group the output i am getting through date type. But i am storing the data in solr using datetime type. Date Format i am using is
Date format :: "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
For e.g. Date is stored in solr as "2013-03-01T20:56:45.000+00:00"
What i want as output is count of dates :: for .e.g.
Date1:: "2013-03-01T20:56:45.000+00:00"
Date2:: "2013-03-01T21:56:45.000+00:00"
Date3:: "2013-03-01T22:56:45.000+00:00"
Date3:: "2013-03-02T22:56:45.000+00:00"
Date4:: "2013-03-02T23:56:45.000+00:00"
So i want the output as two columns ::
Date Count
2013-03-01 3
2013-03-02 2
Here is the code i am using
String url = "http://192.168.0.4:8983/solr";
SolrServer server = new HttpSolrServer(url);
SolrQuery query = new SolrQuery();
query.setQuery("*:*");
query.addFilterQuery("sessionStartTime:[2013-03-01T00:00:00Z TO 2013-03-04T24:00:00Z]");
query.add("group", "true");
query.add("group.field","uniqueId"); // uniqueId is grouping the data
query.add("group.main","true");
query.setRows(9999);
QueryResponse rs=server.query(query);
Iterator<SolrDocument> iter = rs.getResults().iterator();
Help is appreciated.
I know that this is an older question but I am working on something related to this so I thought I would share my solution. Since you are using grouping, rs.getResults() will likely be null. After reading through the SolrJ API and doing some testing on my end, you will find that the results are indeed grouped as you want them to be. To access them, create a variable like such:
List<Group> groupedData = rs.getGroupResponse().getValues().get(0).getValues()
Note that Group is the class org.apache.solr.client.solrj.response.Group
Then, iterate through groupedData, usinig groupedData.get(i).getResult() to get a SolrDocumentList of results for each grouped value. In your example, (assuming the data is ordered as you said it would be), groupedData.get(0) would give you a SolrDocumentList of the three matches that have the date 2013-03-01.
I understand that this is quite the chain of method calls but it does end up getting the results to you. If anyone does know a faster way to get to the data, please feel free to let me know as I would like to know as well.
Refer to the API for GroupResponse for more information
Note that this answer is working on Solr 5.4.0
The output that you are trying to achieve, I believe is better suited to Faceting over grouping. Check out the documentation on Date Faceting more specifically and SolrJ fully supports faceting, see SolrJ - Advanced Usage. For an introduction to Faceting I would recommend reading Faceted Search with Solr

WQL SELECT with optional column

I need to make a query like this:
SELECT PNPDeviceID FROM Win32_NetworkAdapter WHERE AdapterTypeId = 0
Trouble is, the AdapterTypeId column isn't always present. In this case, I just want everything, like so:
SELECT PNPDeviceID FROM Win32_NetworkAdapter
My WQL/SQL knowledge is extremely limited. Can anybody tell me how to do this in a single query?
EDIT:
A bit more background seems to be required: I am querying Windows for device information using WMI, which uses an SQL-like syntax. So, in my example, I am querying for network adapters that have an AdapterTypeId of 0.
That column is not always present however, meaning that if I enumerate through the returned values then "AdapterTypeId" is not listed.
EDIT 2:
Changed SQL to WQL; apparantly this is more correct.
I am assuming you mean the underlying schema is unreliable.
This is a highly unconventional situation. I suggest that you resolve the issue that is causing the column to not always be present, because to have the schema changing dynamically underneath your application is potentially (almost certainly) disastrous.
Update:
OK, so WQL lets you query objects with a SQL-like syntax but, unlike SQL, the schema can change underneath your feet. This is a classic example of a leaky abstraction, and I now hate WQL without ever having used it :).
Since the available properties are in flux, I am guessing that WQL provides a way to enumerate the properties for a given adapter. Do this, and choose which query to run depending upon the results.
After some Googling, there is an example here, which shows how to enumerate through the available properties. You can use this to determine if AdapterTypeId exists or not.
SELECT PNPDeviceID FROM Win32_NetworkAdapter WHERE AdapterTypeId = {yourDesire} OR AdapterTypeId IS NULL
I assume that you mean that this field is missing from the table.
Do you know before submitting the query if this field exists?
If yes then just create SQL dynamically, otherwise It think you will get syntax error in case of missing field
This is not an SQL question. SQL does not contemplate records with varying schemas in a single table source. Instead (as you mention) this is a different system using an "SQL-like" syntax. You'll have better luck if you recast the question using the actual product that you're trying to query, and information how that product deals with variable record structures is probably discussed in the documentation.