get latest version of all articles with pagination - liferay

i would like to get the latest version of all journal articles.
I have a strong requirement on performances issue.
I came up with a very fast query:
SELECT
articleId,
MAX(version) as currentVersion
FROM mf3_liferay.journalarticle
GROUP BY articleId
HAVING currentVersion;
I tough about dynamic queries:
DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(JournalArticle.class);
dynamicQuery.add(RestrictionsFactoryUtil.eq("status", 0))
.addOrder(OrderFactoryUtil.desc("version"))
.setLimit(cur, cur + resultsByPage);
dynamicQuery.setProjection(ProjectionFactoryUtil.groupProperty("version"));
I cannot find a way to add the Having clause.
I read about that:
http://www.liferay.com/fr/documentation/liferay-portal/6.1/development/-/ai/developing-custom-sql-queries-liferay-portal-6-1-dev-guide-en
But I cannot get it to work and I'm worried about performances...

I suggest you use the Search engine instead of querying the database directly.
It offers better performance, and offers pagination.
Getting the latest versions (the 'current') can be done using a field filter on the field 'head', like this:
searchQuery.addRequiredTerm("head", Boolean.TRUE);

Related

Datastax Node.js Cassandra driver When to use a Mapper vs. Query

I'm working with the Datastax Node.js driver and I can't figure out when to use a mapper vs. query. Both seem to be able to perform the same CRUD operations.
With a query:
const q = SELECT * FROM mykeyspace.mytable WHERE id='12345';
client.execute(q).then(result => console.log('This is the data', result);
With mapper:
const tableRow = await tableMapper.find({ id: '12345' });
When should I use the mapper over a query and vice versa?
Mapper is a feature from cassandra-driver released in 2018. Using mapper, cassandra-driver can make a map from your cassandra table to an object in nodejs and you can handle in your nodejs application like a set of document.
Using mapper you can make selects or inserts in your database like said in this article:
https://www.datastax.com/blog/2018/12/introducing-datastax-nodejs-mapper-apache-cassandra
With query method, if you need to use or reuse any property from your json you will need to make a Json.Parse().
The short answer is: whatever you find more comfortable.
The Mapper lets you deal with database data as documents (JavaScript objects), builds the CQL query for you, executes the query and maps the results.
On the other hand, the core driver only supports executing CQL queries that you have to write yourself.

Does ArangoDB java driver provides API for GEO_INTERSECTS

For library arangodb-spring-data, version 3.2.3, is there any possibility to query for GEO_INTERSECTS functionality using the java api provided by the driver?
Currently I am using an AQL query in my code:
LET areaLiteral = GEO_POLYGON(...)
FOR doc IN MyDocuments
FILTER GEO_INTERSECTS(areaLiteral, doc.geometry)
LIMIT 5 RETURN doc
So far in the official documentation couldn't find anything related to GEO_INTERSECTS, also in this example: https://github.com/arangodb/spring-data-demo#geospatial-queries
I have checked the source code of the driver, but didn't find anything related to keyword "INTERSECTS" which would construct this query behind the scenes.
It is not yet supported, the only supported geospatial queries are Near and Within:
https://www.arangodb.com/docs/3.6/drivers/spring-data-reference-repositories-queries-derived-queries.html#geospatial-queries

Marklogic QueryByExample in collection NodeJS

TLDR
Is there a way to limit queryByExample to a collection in NodeJS?
Problem faced
I have a complex query with some optional fields (i.e. sometimes some search fields will be omitted). So I need to create a query dynamically, e.g. in JSON. QueryByExample seems to be the right tool to use here as it gives me that flexibility to pass a JSON. However my problem is that I would like to limit my search to only one collection or directory.
e.g. I was hoping for something like
searchJSON = {
title: { $word: "test" },
description: { $word: "desc" }
};
//query
db.documents.query(qb.where(
qb.collection("collectionName"),
qb.byExample(searchJSON)
)).result()...
In this case searchJSON could have been built dynamically, for example maybe sometimes title may be omitted from the search.
This doesn't work because the query builder only allows queryByExample to be the only query. But I'd instead like to built a dynamic search query which is limited to a collection or directory.
At present, I think you would have to express the query with QueryBuilder instead of Query By Example using
qb.and([
qb.collection('collectionName'),
qb.word('title', 'test'),
qb.word('description', 'desc')
])
See http://docs.marklogic.com/jsdoc/queryBuilder.html#word
That said, it should be possible for the Node.js API to relax that restriction based on the fixes in MarkLogic 9.0-2
Please file an issue on https://github.com/marklogic/node-client-api

Neo4j-php retrieve node

I have been exclusively using cypher queries of this client for Neo4j because there is no out of the box way of doing many things. One of those id to get nodes. There is no way to retrieve them without knowing their id, which is very low level. Any idea on how to run a
$client->findOne('property','value');
?
It should be straightforward but it isn't from the documentation.
Make Indexes on the properties you want to search, from a newly created $personNode
$personIndex = new \Everyman\Neo4j\NodeIndex($client, 'person');
$personIndex->add($personNode, 'name', $personNode->name);
Then later to search, the new PHP object $personIndex will reference the same, populated index as above.
$personIndex = new \Everyman\Neo4j\NodeIndex($client, 'person');
$match = $personIndex->findOne('name', 'edoceo');

Paging through Cassandra using QueryBuilder

The DataStax documentation says that to page through all data, the following CQL query is useful:
SELECT * FROM test WHERE token(k) > token(42);
Is it possible to build this query using the QueryBuilder? It provides a token method, but that seems to work only on column names, not on values.
Ideally, the value (in the example: 42) is of type Object, just like in the eq/gte/lte functions.
Try using automatic paging with the .fetchSize method. It uses token under the hood:
Automatic paging is introduced Cassandra 2.0. Automatic paging allows the developer to iterate on an entire ResultSet without having to care about its size: some extra rows are fetched as the client code iterate over the results while the old ones are dropped. The amount of rows that must be retrieved can be parameterized at query time. In the Java Driver this will looks like:
Statement stmt = new SimpleStatement("SELECT * FROM images");
stmt.setFetchSize(100);
ResultSet rs = session.execute(stmt);
Source: http://www.datastax.com/dev/blog/client-side-improvements-in-cassandra-2-0
QueryBuilder.fcall("token", value) ;
can solve the problem!

Resources