Order by another table with Liferay's DynamicQuery - java

I have a problem while I'm making a Dynamic Query in Liferay 6. I'm trying to make a query to order JournalArticles based on their view count. The view count is specified in another table (AssetEntry).
I'm stuck with this:
DynamicQuery query = DynamicQueryFactoryUtil.forClass(
JournalArticle.class, "articleParent", PortalClassLoaderUtil.getClassLoader());
//adding criterions
query.add(...);
DynamicQuery dq0 = DynamicQueryFactoryUtil.forClass(AssetEntry.class, "asset",
PortalClassLoaderUtil.getClassLoader())
.setProjection(ProjectionFactoryUtil.property("asset.classPK"))
.add(PropertyFactoryUtil.forName("asset.companyId")
.eqProperty("articleParent.companyId"))
.add(PropertyFactoryUtil.forName("asset.groupId")
.eqProperty("articleParent.groupId"));
query.add(PropertyFactoryUtil.forName("articleParent.resourcePrimKey").in(dq0))
.addOrder(OrderFactoryUtil.desc("asset.viewCount"));
With this I get an error message saying: could not resolve property: asset of: com.liferay.portlet.journal.model.impl.JournalArticleImpl.
If I remove the addOrder-call, this error disappears. How should I add the order statement so the main query is aware of asset.viewCount?

AssetEntryQuery assetEntryQuery = new AssetEntryQuery();
assetEntryQuery.setClassName(JournalArticle.class.getName());
assetEntryQuery.setXXX //adding criterions
assetEntryQuery.setOrderByCol1("viewCount");
List<AssetEntry> assetEntries = AssetEntryServiceUtil.getEntries(assetEntryQuery);

I am afraid that there is no direct way to do this with the DynamicQuery API.
I think you would need to use Service builder Finders i.e. Custom Query with Service builder.

You can't use dynamic query because there is no direct reference from JournalArticle entity to AssetEntry entity.
One possibility is to retrieve ordered ids of articles from the AssetEntry table (basically you dq0), then do another query and do the sorting programatically (you have the ids ordered).
Finally I think that this line
query.add(PropertyFactoryUtil.forName("articleParent.resourcePrimKey").in(dq0))
doesn't do what you think it does. resoucePrimKey is reference to resource table for permissions. You need to use id column.

Related

How to evolve schema in Janusgraph?

I uploaded movie and user data to janusgraph and initially I made index on movieId but, later I realised I need to index movie title as well. I need to do query based on movie title and without indexing movie id, it's giving me warning "Query requires iterating over all vertices". So, I added the code:
JanusGraphManagement mgmt = graph.openManagement();
PropertyKey title = mgmt.getPropertyKey("title");
JanusGraphManagement.IndexBuilder movieNameIndexBuilder = mgmt.buildIndex("title", Vertex.class)
.addKey(title);
movieNameIndexBuilder.unique();
JanusGraphIndex movieTitleIndex = movieNameIndexBuilder.buildCompositeIndex();
mgmt.setConsistency(movieTitleIndex, ConsistencyModifier.LOCK);
mgmt.commit();
Still I'm getting the same warning "Query requires iterating over all vertices" when I'm querying on movie title.
Thank you
Got the solution from Janusgraph gitter channel:
The index isn't available immediately if the the indexed property key was created in a previous management transaction as JanusGraph might need to reindex existing data now. That is a process you have to trigger manually. You can read more about this in the chapter Index Management of the docs.
That is why it's recommended to create all indices in the same transaction where you create the property keys if possible

Querying on Collection attribute in Corda

I'm trying to search value inside Corda unconsumed states on a collection Field.
I'm able to search on String field using -
Field uniqueAttributeName = MySchema.PersistentIOU.class.getDeclaredField("fieldname");
CriteriaExpression uniqueAttributeEXpression = Builder.equal(uniqueAttributeName, "valueToSearch");
QueryCriteria customCriteria = new QueryCriteria.VaultCustomQueryCriteria(uniqueAttributeEXpression);
result = rpcOps.vaultQueryByCriteria(customCriteria, MyState.class).getStates();
Above worked fine when "fieldname" is String but I have another field which is List and I'm not sure how to search inside List for a specific value.
Please assist.
After a quick chat with #Roger3cev, we think the best way is to amend your ORM wrapper such that you have a parent - child relationship between the state and the list of fields you want to have in that list. Once you do this, you can use the JDBC connection available to you to query against the child state and then use the relationship to the parent to get the Corda state.

Java Couchbase Querying to find a document's ID?

I'm new to couchbase. I'm using Java for this. I'm trying to remove a document from a bucket by looking up its ID with query parameters(assuming the ID is unknown).
Lets say I have a bucket called test-data. In that bucked I have a document with ID of 555 and Content of {"name":"bob","num":"10"}
I want to be able to remove that document by querying using 'name' and 'num'.
So far I have this (hardcoded):
String statement = "SELECT META(`test-data`).id from `test-data` WHERE name = \"bob\" and num = \"10\"";
N1qlQuery query = N1qlQuery.simple(statement);
N1qlQueryResult result = bucket.query(query);
List<N1qlQueryRow> row = result.allRows();
N1qlQueryRow res1 = row.get(0);
System.out.println(res1);
//output: {"id":"555"}
So I'm getting a json that has the document's ID in it. What would be the best way to extract that ID so that I can then remove the queryed document from the bucket using its ID? Am I doing to many steps? Is there a better way to extract the document's ID?
bucket.remove(docID)
Ideally I'd like to use something like a N1q1QueryResult to get this going but I'm not sure how to set that up.
N1qlQueryResult result = bucket.query(select("META.id").fromCurrentBucket().where((x("num").eq("\""+num+"\"")).and(x("name").eq("\""+name+"\""))));
But that isn't working at the moment.
Any help or direction would be appreciated. Thanks.
There might be a better way which is running this kind of query:
delete from `test-data` use keys '00000874a09e749ab6f199c0622c5cb0' returning raw META(`test-data`).id
or if your fields has index:
delete from `test-data` where name='bob' and num='10' returning raw META(`test-data`).id
This query deletes the specified document with given document key (which is meta.id) and returns document id of deleted document if it deletes any document. Returns empty if no documents deleted.
You can implement this query with couchbase sdk as follows:
Statement statement = deleteFrom("test-data")
.where(x("name").eq(s("bob")).and(x("num").eq(s("10"))))
.returningRaw(meta(i("test-data")).get("id"));
You can make this statement parameterized or just execute like that.

GAE Datastore querying by index

I have created entities in the datastore. I want to use the index assigned to them by the datstore for queries.
i.e get an iterable back where the id is greater than a given number
e.g.
Query q = new Query("MyEntity");
q.addFilter("id",Query.FilterOperator.GREATER_THAN_OR_EQUAL, startId);
PreparedQuery pq = datastore.prepare(q);
I know I can get back an individual entity back via id - but how to get a list ?
Cheers,
Iterable<Entity> myEntities = pq.asIterable();
List<Entity> myEntitiesInAList = pq.asList(FetchOptions.Builder.withChunkSize(500));
Side note:
"id" is not the name of the key assigned automatically by App Engine. I think you must use __key__ as the property name to do queries on it, and construct a full key as the search parameter, not just the long id.
If your intent is to remember where you left off and continue there on a subsequent query, consider using a query cursor. The example on that page might give you some further options.

Association of 4 tables in hibernate

I have 4 tables involved in this query.
Campaign - many to one business
Business - one to many client
Client - one to one contact
Contact
In contact there is the field contact_name which is unique. I need to retrieve all campaigns related to contact(via client and business) which campaign field type equals 2.
What is the best way to do it with hibernate?
In SQL is will look like this:
select *
from campaign,contact, business, client
where campaign.type=2
and client.contact_id = contact.contact_id
and contact.name = 'Josh'
and client.business_id = business.business_id
and campaign.campaign_id = business.business_id
I think that the following should work.
from Compaign where Compaign.type=2 and compaign.business.client.contact.contact_name=:name
You can execute native SQL Queries too using createSQLQuery() method of Session.
You can also use Scalar Property to avoid the overhead of using ResultSetMetadata.
You can find more information on this from here

Categories

Resources