AEM Find Assets Referenced By Image Components - aem

I'm trying to find pages in AEM 6.1 that reference images from the DAM that are wider than 1280px. I'm really struggling to figure out if this is possible via a single JCR_SQL2 query or not. I've tried many things that have not worked (get ParseException when trying to query from CRXDE), but I think the following somewhat conveys what I'm after, except I think I'd need some additional joins, starting at cq:Page, to get pages instead of the actual image component nodes:
SELECT s.* from [nt:unstructured] as s
INNER JOIN [dam:Asset] as a on ISSAMENODE(a, s.[fileReference])
WHERE a.[jcr:content/metadata/tiff:ImageWidth] >= 1280
I've tried joining on jcr:path equality as well, but I can't get anything to actually run.

I believe you do not need to join anything to achieve what you are looking for. I tested the following in crx-de lite "Tools.Query":
Finding assets:
SELECT * from [dam:Asset] as a
WHERE a.[jcr:content/metadata/tiff:ImageWidth] >= 1000
Finding references to an asset:
SELECT * FROM [nt:unstructured] AS r
WHERE r.fileReference = '/content/dam/my-images/my-icon.png'
AND ISDESCENDANTNODE(r, '/content') // optimization to reduce query space
Most join examples revolve around parent-child relationships ISCHILDNODE(parent, child), which don't apply to this use case. Unfortunately, joining the String r.fileReference to Resource a has been beyond my research so far.
The closest example I could find was from #6 on http://labs.6dglobal.com/blog/2014-10-07/9-jcr-sql-2-queries-every-aem-dev-should-know/
SELECT parent.* FROM [cq:Page] AS parent
INNER JOIN [nt:base] AS child ON ISCHILDNODE(child,parent)
WHERE ISDESCENDANTNODE(parent, '/content') AND child.[cq:template] = '/libs/cq/personalization/templates/campaign'

Related

Replace correlated subquery with join

I'd like to replace the following ABAP OpenSQL snippet (in the where clause of a much bigger statement) with an equivalent join.
... AND tf~tarifart = ( SELECT MAX( tf2~tarifart ) FROM ertfnd AS tf2 WHERE tf2~tariftyp = e1~tariftyp AND tf2~bis >= e1~bis AND tf2~ab <= e1~ab ) ...
My motivation: Query migration to ABAP CDS views (basically plain SQL with in comparison somewhat reduced expressiveness). Alas, correlated subqueries and EXISTS statements are not supported.
I googled a bit and found a possible solution (last post) here https://archive.sap.com/discussions/thread/3824523
However, the proposal
Selecting MAX(value)
Your scenarion using inner join to first CDS view
doesn't work in my case.
tf.bis (and tf.ab) need to be in the selection list of the new view to limit the rhs of the join (new view) to the correct time frames.
Alas, there could be multiple (non overlapping) sub time frames (contained within [tf.ab, tf.bis]) with the same tf.tarifart.
Since these couldn't be grouped together, this results in multiple rows on the rhs.
The original query does not have a problem with that (no join -> no Cartesian product).
I hope the following fiddle (working example) clears things up a bit: http://sqlfiddle.com/#!9/8d1f48/3
Given these constraints, to me it seems that an equivalent join is indeed impossible. Suggestions or even confirmations?
select doc_belzart,
doc_tariftyp,
doc_ab,
doc_bis,
max(tar_tarifart)
from
(
select document.belzart as doc_belzart,
document.tariftyp as doc_tariftyp,
document.ab as doc_ab,
document.bis as doc_bis,
tariff.tarifart as tar_tarifart,
tariff.tariftyp as tar_tariftyp,
tariff.ab as tar_ab,
tariff.bis as tar_bis
from dberchz1 as document
inner join ertfnd as tariff
on tariff.tariftyp = document.tariftyp and
tariff.ab <= document.ab and
tariff.bis >= document.bis
) as max_tariff
group by doc_belzart,
doc_tariftyp,
doc_ab,
doc_bis
Translated in English, you seem to want to determine the max applicable tariff for a set of documents.
I'd refactor this into separate steps:
Determine all applicable tariffs, meaning all tariffs that completely cover the document's time interval. This will become your first CDS view, and in my answer forms the sub-query.
Determine for all documents the max applicable tariff. This will form your second CDS view, and in my answer forms the outer query. This one has the MAX / GROUP BY to reduce the result set to one per document.

merge features n time

Here is my issue, I'm working on a project of water supply where I have to merge line features representing pipes if they have the same material of construction and if they are touching each other. The merge is done two by two what it means that some features will be duplicated in some cases like described in the figure below :
this shows exactly my issue. After the merge I will get three records but what I want is just one record which encompasses the whole pipes that fill the conditions put in the where clause :
Here is the query that helps me do the merge :
drop table if exists touches_material;
create table touches_material as
select distinct a.*,
st_Union(a.geom,b.geom) as fusion from pipe a, pipe b
where a.id < b.id and a.material = b.material and
st_touches(a.geom,b.geom)
group by a.id,a.geom,b.geom
the following picture picture shows the expected result on a test data, it's realized via QGIS GIS software :
but this is what I' getting with my query :
if you have any idea about how to achieve the aim that I invoked, I would be very thankful to get an answer from you. Best regards.

Faster/efficient alternative to IN clause in custom/native queries in spring data jpa

I have a custom query along these lines. I get the list of orderIds from outside. I have the entire order object list with me, so I can change the query in any way, if needed.
#Query("SELECT p FROM Person p INNER JOIN p.orders o WHERE o.orderId in :orderIds)")
public List<Person> findByOrderIds(#Param("orderIds") List<String> orderIds);
This query works fine, but sometimes it may have anywhere between 50-1000 entries in the orderIds list sent from outside function. So it becomes very slow, taking as much as 5-6 seconds which is not fast enough. My question is, is there a better, faster way to do this? When I googled, and on this site, I see we can use ANY, EXISTS: Postgresql: alternative to WHERE IN respective WHERE NOT IN or create a temporary table: https://dba.stackexchange.com/questions/12607/ways-to-speed-up-in-queries-under-postgresql or join this to VALUES clause: Alternative when IN clause is inputed A LOT of values (postgreSQL). All these answers are tailored towards direct SQL calls, nothing based on JPA. ANY keyword is not supported by spring-data. Not sure about creating temporary tables in custom queries. I think I can do it with native queries, but have not tried it. I am using spring-data + OpenJPA + PostgresSQL.
Can you please suggest a solution or give pointers? I apologize if I missed anything.
thanks,
Alice
You can use WHERE EXISTS instead of IN Clause in a native SQL Query as well as in HQL in JPA which results in a lot of performance benefits. Please see sample below
Sample JPA Query:
SELECT emp FROM Employee emp JOIN emp.projects p where NOT EXISTS (SELECT project from Project project where p = project AND project.status <> 'Active')

SQL Server, views usage count

My scenario is like this:
I have a couple of views in my databse (SQL Server 2005).
These views are queried from Excel across the organization.
My goal is to identify those views which have not been used by anyone for a long time.
Is there a way to count the number of times a view has been requested since a specific date?
Thanks
Avi
You can use following query to get some queries those executed. You can place "Like" operator in dest.text field to check for views.
SELECT deqs.last_execution_time AS [Time], dest.text AS [Query]
FROM sys.dm_exec_query_stats AS deqs
CROSS APPLY sys.dm_exec_sql_text(deqs.sql_handle) AS dest
ORDER BY deqs.last_execution_time DES
I think a combination of DMVs and sysobjects could tell you this. This should hopefully show you all queries run that refer to a view, the name of the view, when it was last run etc.
SELECT s2.text AS Query,
so.name AS ViewName,
creation_time,
last_execution_time,
execution_count
FROM sys.dm_exec_query_stats AS s1
CROSS APPLY sys.Dm_exec_sql_text(sql_handle) AS s2
INNER JOIN sys.objects so
ON so.object_id = s2.objectid
AND so.type = 'V'
I don't think that you'll be able to do this unless you are running a trace 24/7. You could turn on auditing in order to monitor it. But, it would be a big task for however has to read through the logs.

ZF_DB: how to make simple select for two or more tables without join?

Example:
SELECT `cat`.`id_catalog`, COUNT(parent.id_catalog) - 1) AS `level` FROM `tbl_catalog` AS `cat`, `tbl_catalog` AS `parent` WHERE (cat.`left` BETWEEN parent.`left` AND parent.`right`) GROUP BY `cat`.`id_catalog` ORDER BY `cat`.`left` ASC
It doesn't seem to work if it use ZF. ZF create this query with join only. How to create the select without join in ZF_DB.
By the way may be I do smth wrong in this query. It is simple nested set DB with parent, left and right fields. Perhaps there are another way to use join to get deep for some node. Anyway it would be interesting to get answer for both way:)
Thanks in advance to all who looks it through:)