简体   繁体   中英

Neo4j/Cypher query limit order by latest created

I have a collection of :Product nodes and I want to return latest 100. Consider global query like:

MATCH (p:Product) RETURN p LIMIT 100

From what I can see it returns oldest nodes first. Is there a way of getting newest on top?

Order by won't be an option as number of products can be millions.

UPDATE

I ended up creating a dense node (:ProductIndex) . Each time I create product I add it to the index (:Product)-[:INDEXED]->(:ProductIndex) . With dense nodes rel chain will be ordered by latest first so that query below will return newest records on top

MATCH (p:Product)-[:INDEXED]->(:ProductIndex)
RETURN p
LIMIT 1000

I can always keep index fixed size as I don't need to preserve full history.

Is the data model such that the products are connected in a list (eg (:Product)-[:PREVIOUS]->(:Product)?

Can you keep track of the most recent node? Either with a time stamp that you can easily locate or another node connected to your most recent product node.

If so, you could always query out the most recent ones with a query similar to the following.

match (max:Date {name: 'Last Product Date'})-->(latest:Product) 
with latest
match p=(latest)-[:PREVIOUS*..100]->(:Product)
return nodes(p)
order by length(p) desc
limit 1

OR something like this where you select

match (max:Date {name: 'Product Date'}) 
with max
match p=(latest:Product)-[:PREVIOUS*..100]->(:Product)
where latest.date = max.date
return nodes(p)
order by length(p) desc
limit 1

Another approach, still using a list could be to keep an indexed create date property on each product. But when looking for the most recent pick a control date that doesn't go back to the beginning of time so you have a smaller pool of nodes (ie not millions). Then use an max function on that smaller pool to find the most recent node and follow it back by however many you want.

match (latest:Product)
where latest.date > {control_date}
with max(latest.date) as latest_date
match p=(product:Product)-[:PREVIOUS*..100]->(:Product)
where product.date = latest_date
return nodes(p)
order by length(p) desc
limit 1 

Deleting a node in a linked list is pretty simple. If you need to perform this search a lot and you don't want to order the products, I think keeping the products in a list is a pretty good graph application. Here is an example of a delete that maintains the list.

match (previous:Product)<-[:PREVIOUS]-(product_to_delete:Product)<-[:PREVIOUS]-(next:Product)
where product_to_delete.name = 'name of node to delete'
create (previous)<-[:PREVIOUS]-(next)
detach delete product_to_delete
return previous, next

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM