jcr sql-2 get node name - aem

i am working on aem 6.3 and would like to get page name
SELECT * FROM [cq:Page] WHERE ISDESCENDANTNODE("/content/Product/Silhouettes/Accessories/Bands/Headband")
If I need to retrieve name of the nodes using sql-2 , how do I achieve it?

You can specify column constraints like title, node name, etc this way -
SELECT nodeSet.name, nodeset.title
FROM [cq:Page] AS nodeSet
WHERE ISDESCENDANTNODE("/content/Product/Silhouettes/Accessories/Bands/Headband")
Note: the query tool in AEM(Tools -> Query) will not list the query results according to the columns you've mentioned, it will only list the node paths.
You can look at using /etc/importers/bulkeditor.html or AEM fiddle tool to visualize the query results based on column constraints.
If you want to achieve this programmatically, you can use the same query as you've mentioned in your question and use javax.jcr.query.* and javax.jcr.Node.* API's to retrieve just about any property from the query result. This article here should help you achieve this programatically.

Use the ResourceResolver API to execute and obtain the query results:
final Iterator<Resource> pagesIterator = resolver.findResources('<your_query_here>', javax.jcr.query.Query.JCR_SQL2);
while (pagesIterator.hasNext()) {
final Resource pageResource = pagesIterator.next();
LOG.info(pageResource.getName());
}
However, please note that if you are using any version higher then CQ 5.6, you should use instead the Page API.
In this case, the listChildren(Filter<Page> filter, boolean deep) method will do the job.
The PageFilter parameter may be used if you want to filter through pages of some kind. So if no extra criteria for your page finding algorithm, your may pass null or a new empty object.
The boolean parameter: if false it returns only direct child pages, and if true would list all the descendant pages of the given page.
Therefore, the equivalent solution of the SQL Query which would provide you the same end results would be:
Iterator<Page> rootPageIterator = rootPage.listChildren(null, true);

Related

How to improve performance on nested graphql connections when using pagination

I'm trying to implement some kind of a basic social network project. It has Posts, Comments and Likes like any other.
A post can have many comments
A post can have many likes
A post can have one author
I have a /posts route on the client application. It lists the Posts by paginating and shows their title, image, authorName, commentCount and likesCount.
The graphql query is like this;
query {
posts(first: 10, after: "123456") {
totalCount
edges {
node {
id
title
imageUrl
author {
id
username
}
comments {
totalCount
}
likes {
totalCount
}
}
}
}
}
I'm using apollo-server, TypeORM, PostgreSQL and dataloader. I use dataloader to get author of each post. I simply batch the requested authorIds with dataloader, get authors from PostgreSQL with a where user.id in authorIds query, map the query result to the each authorId. You know, the most basic type of usage of dataloader.
But when I try to query the comments or likes connection under each post, I got stuck. I could use the same technique and use postId for them if there was no pagination. But now I have to include filter parameters for the pagination. And there maybe other filter parameters for some where condition as well.
I've found the cacheKeyFn option of dataloader. I simply create a string key for the passed filter object to the dataloader, and it doesn't duplicate them. It just passes the unique ones to the batchFn. But I can't create a sql query with TypeORM to get the results for each first, after, orderBy arguments separately and map the results back to the function which called the dataloader.
I've searched the spectrum.chat source code and I think they don't allow users to query nested connections. Also tried Github GraphQL Explorer and it lets you query nested connections.
Is there any recommended way to achieve this? I understood how to pass an object to dataloader and batch them using cacheKeyFn, but I can't figure out how to get the results from PostgreSQL in one query and map the results to return from the loader.
Thanks!
So, if you restrict things a bit, this is doable. The restriction is to only allowed batched connections on the first page of results, e.g. so all the connections you're fetching in parallel are being done with the parameters. This is a reasonable constraint because it lets you do things like get the first 10 feed items and the first 3 comments for each of them, which represents a fairly typical use case. Trying to support independent pagination within a single query is unlikely to fulfil any real world use cases for a UI, so it's likely an over-optimisation. With this in mind, you can support the "for each parent get the first N children" use case with PostgreSQL using window.
It's a bit fiddly, but there are answers floating around which will get you in the right direction: Grouped LIMIT in PostgreSQL: show the first N rows for each group?
So use dateloader how you are with cacheKeyFn, and let your loader function recognise whether you can perform the optimisation (e.g. after is null and all other arguments are the same). If you can optimise, use a windowing query, otherwise do unoptimised queries in parallel as you would normally.

DOMINO REST API get Collection sort column

Hi I'm trying to get a sorted Collection from the Domino Rest Api. My database name is "Test/JSON_Views.nsf" and my views name "List".
The endpoint I use is
**/Test/JSON_Views.nsf/api/data/collections/name/List?sortcolumn=title&sortorder=ascending&count=20
But the JSON-Response entries aren't sorting by title in ascending order.
Should I make any settings to the column properties in the designer? If I set descending there for the title-column it works. But I want to change the sorting in my external java-application.
Is my endpoint correct? I use this Domino API Docu as Reference.
Add an additional sorting to your title column:
This gives the API the possibility to sort by title in both directions. You can do this with other columns too so you are very flexible in sorting this way.
The doc says that if the column isn't sorted in design then the sortcolumn parameter has no effect, so the answer is "Yes" you should change the design of the desired column. If doing that is unworkable in whatever context you use it, then create a second view and use that instead.

How to fetch distinct list from SpringData without using query annotation?

I am using 2 different properties to fetch distinct list eg
findDistinctBy<propertyName>And<propertyName>In(List<String> list).
My actual Spring jpa statement is
List<PojoClass> findAllByTpIdInAndDistinctMobile(List<String> edgeIds);
where TpId & Mobile are 2 different properties in PojoClass. I need to implement this without using Query annotation. Any suggestions of queryDsl will also do.
The question needs to be more clear.What exactly do you intend to achieve when the input is a list of Ids?
There is no option to provide a list to findAll unless it is an Id.
A simple way would be to loop the the input list in service and append the result to a result list.
for(String edgeId:edgeIds){
resultList.addAll(findByEdgeId(edgeId));
}
Updated code after #Tejas comment
for(Pojo pojo:Pojos){
resultList.addAll(findDistinctPojoByPropert1OrPropert2(String pojo.getProperty1(),String pojo.getProperty2());
}

Select * for Github GraphQL Search

One of the advantage of Github Search v4 (GraphQL) over v3 is that it can selectively pick the fields that we want, instead of always getting them all. However, the problem I'm facing now is how to get certain fields.
I tried the online help but it is more convolution to me than helpful. Till now, I'm still unable to find the fields for size, score and open issues for the returned repository(ies).
That's why I'm wondering if there is a way to get them all, like Select * in SQL. Thx.
GraphQL requires that when requesting a field that you also request a selection set for that field (one or more fields belonging to that field's type), unless the field resolves to a scalar like a string or number. That means unfortunately there is no syntax for "get all available fields" -- you always have to specify the fields you want the server to return.
Outside of perusing the docs, there's two additional ways you can get a better picture of the fields that are available. One is the GraphQL API Explorer, which lets you try out queries in real time. It's just a GraphiQL interface, which means when you're composing the query, you can trigger the autocomplete feature by pressing Shift+Space or Alt+Space to see a list of available fields.
If you want to look up the fields for a specific type, you can also just ask GraphQL :)
query{
__type(name:"Repository") {
fields {
name
description
type {
kind
name
description
}
args {
name
description
type {
kind
name
description
}
defaultValue
}
}
}
}
Short Answer: No, by design.
GraphQL was designed to have the client explicitly define the data required, leading to one of the primary benefits of GraphQL, which is preventing over fetching.
Technically you can use GraphQL fragments somewhere in your application for every field type, but if you don't know which fields you are trying to get it wouldn't help you.

How to make a GET request using a filter on a datetime property with EspoCRM REST API?

EspoCRM provides a REST API that sadly has only incomplete documentation. Especially the filters that can be used with a GET request are not documented:
where - (array) filters;
From using Firebug I've discovered that a filter consists of three query parameters:
where[0][field]=somefield
where[0][type]=somoperator
where[0][value]=somevalue
Example, filter on name=Foo:
?where[0][field]=name&where[0][type]=equals&where[0][value]=Foo
The meaning of equals is not documented, as are the possible filter types.
Now I want to filter a collection on a datetime field modifiedAt. I have no idea what the proper values for type and value would be to find all entities that have been modified after a given datetime.
How can the EspoCRM REST API be used for this?
After playing around with the EspoCRM web GUI, I was able to make a search that uses the filter I need. The query parameters are:
where[0][type]=after
where[0][field]=modifiedAt
where[0][value]=2016-06-01 16:12:00
where[0][dateTime]=true
where[0][timeZone]=Europe%2FBerlin