Neo4j - Searching from an array of nodes - neo4j

In my situation I've a bunch of nodes that represent the users
and they have relation to books they read.
This user have a property that says where they are from, and I added them to an index, based on their country.
So I would like to search in the index for users from one country, and list the books that people from there read more, some sorting by grouping.
could any one give me a help how to do this?
I'm having some trouble getting users from the index, and doing the query

Couple of assumptions based on your descriptions:
users have a country property, it contains e.g. France as value
you have a index called users and you store the user node's country property there
relationship type to connect users and books is READ
book nodes have a title property
Based on these assumptions the cypher query would look like:
start user=node:users(country='France')
match user-[:READ]->book
return book.title, count(*) as rank
order by rank desc
limit 20
side note: best approach to ask this kind of questions is to create a sample graph on http://console.neo4j.org and share your setup on SO.

Related

Solr join across multiple collections and fetch data from both collections

I have 2 solr collections:
Ads {id, title, body, description, etc etc)
AdPlacement (ad_id, placement_id, price)
Each Ad can have 500-1000 placements, with different prices.
The search usecase is where I have a placement and some search keyword and I want to find the Ads that map the keyword provided in the title/body/description fields and it should be sorted by the price in the AdPlacement collection for the given placement. We would like to get the Ad details and the price in the output returned.
Is there any way to achieve this in solr using join across multiple collections? What I have read so far says you can only get data from one collection and use the other one just for filtering.
Solr is a Document database and supports nested documents so ideally you would want to model such that your add placement records are a part of the Ad document. This would be the better way to handle your scenario. Please go through this blog Solr Nested Objects and the relevant Solr documentation
In case modifying the document structure is not an option then consider this documentation which mentions about allowing some level of join between collections.

How to design neo4j db nodes that have ordered relationship with other nodes

I'm trying to design a Neo4j graph database, and I will illustrate my specific requirement. I'm designing an app that allows users to collaborate on the books and magazines they have read. Requirements:
The same Book can be read by multiple people
The order in which a specific person reads the books is important. For example, I want to be able to represent that Person A read Books B1 and B2 in that order, while Person B may have read Books B3, B2 and B1 in that order.
I'm thinking of having nodes representing a Book, Magazine, Person, etc.
What is the best way to ensure the order/sequence information? A couple of options I thought about:
Store a order ID or timestamp in the relationship between a Person and a Book node and use that to query all Books read by the person in the right order.
Store a Next/Previous relationship between Book nodes, but this approach will not work because the order can vary depending on which person read the books.
To me this is the way to go, easy and effective.
Store a order ID or timestamp in the relationship between a Person and
a Book node and use that to query all Books read by the person in the
right order.
Storing a Next/Previous relationship will not work, because you would have to save UserID in the NEXT relationship between books and that is just nonsense.

Combining joins with other joins or regular queries

I'd like to combine Solr join queries with regular queries. As an example, suppose I want to find all stores in Jyväskylä (Finland) selling guide books. If documents for stores have the fields city and productIds and documents for products have the fields productType and productId in my index, I'd expect something like this to work:
{!join from=productIds to=productId}productType:"guide book" city:Jyväskylä
However, join queries are a particular kind of LocalParams and those are effective for the entire query. Therefore, this query would select documents that have productType=guide book and city=Jyväskylä, which doesn't make any sense.
Worse, suppose I want to look for stores that carry guide books and are located in cities with a population over 1000 people. I'd need two joins for that (to select products and cities).
Of course, I can split this into a query (q) and a filter query (fq), but that limits me to two kinds of queries (so, either one regular query and one join query or two joins), and more importantly abuses the concept of queries and filter queries.
My question therefore: how can I combine regular and join queries and how can I have multiple join queries?
I think I've got it: there can be more than one filter query and each can have its own join clause. Solr's admin interface won't let you enter more than one query in the fq field, but it's possible through the "Raw Query Parameters" field.
I'm not sure how efficient this is, though.

Can I Order Results Using Two Columns from Different Tables?

I have a Rails application featuring a city in the US. I'm working on a database process that will feature businesses that pay to be on the website. The goal is to feature businesses within an hour's drive of the city's location in order to make visitors aware of what is available. My goal is to group the businesses by city where the businesses in the city are listed first then the businesses from the next closest city are displayed. I want the cities to be listed by distance and the businesses within the city group to be listed by the business name.
I have two tables that I want to join in order to accomplish this.
city (has_many :businesses) - name, distance
business (belongs_to :city) - name, city_id, other columns
I know I can do something like the statement below that should only show data where business rows exist for a city row.
#businesses = City.order(“distance ASC").joins('JOIN businesses ON businesses.city_id = cities.id')
I would like to add order by businesses.name. I've seen an example ORDER BY a.Date, p.title which referencing columns from two databases.
ORDER BY a.Date, p.title
Can I add code to my existing statement to order businesses by name or will I have to embed SQL code to do this? I have seen examples with other databases doing this but either the answer is not Rails specific or not using PostgreSQL.
After lots more research I was finally able to get this working the way I wanted to.
Using .joins(:businesses) did not yield anything because it only included the columns for City aka BusinessCity and no columns for Business. I found that you have to use .pluck or .select to get access to the columns from the table you are joining. This is something I did not want to do because I foresee more columns being added in the future.
I ended up making Business the main table instead of BusinessCity as my starting point since I was listing data from Business on my view as stated in my initial question. When I did this I could not use the .joins(:business_cities) clause because it said the relation did not exist. I decided to go back to what I had originally started with using Business as the main table.
I came up with the following statement that provides all the columns from both tables ordered by distance on the BusinessCity table and name on the Business table. I was successful in added .where clauses as needed to accommodate the search functionality on my view.
#businesses = Business.joins("JOIN business_cities ON business_cities.id = businesses.business_city_id").order("business_cities.distance, businesses.name")

neo4j order by on relationship not looking at index

I have been looking into this problem for while now. I have neo4j setup with the following schema :
User has friends and User likes movie. One of my primary usecases is to get all the movies liked by all my friends. This is how I am doing it:
start user=node:userIndex(uid="1234")
match user-[friend_rela:FRIENDS]-(friend)-[movie_rela:LIKE]->movie
return distinct movie,movie_rela,friend
order by movie_rela.timeStamp desc
skip 0
limit 5;
It works allright, but the time taken by the query is in the order of ~10seconds. If I remove the 'order by movie_rela.timeStamp desc' it comes back in around 2 seconds. I have indexed the timestamp property in the relationship. I then read that Neo4J does not honor indexes on an Order by clause. Is there some way I can fix this ? The above query is one of my primary usecases.
Thanks.
You can redesign your graph. Like eg. suppose a friend can like multiple movies and different timestamps. So your graph can be
(u:User)-[:FRIENDS]->(friend:User)-[r1:Like]->(m1:Movie)-[r2:Like]->(m2:Movie)-...
Where the relationship Like is created from User in an order from latest to oldest. And r1,r2 will contain the timestamp as well as userid to uniquely form the path from a particular user to a movie in the entire chain. The Movie connected to User directly is the latest and as the distance (the number of Like relationship) increases between the User Node and the mOvie node, that particular movie is watched oldest.(you can reverse the order as per your convenience)
The benefit of having such design will be that there would be no requirement of ordering based on timestamp.
For any user if you wish to get all the movies he liked then just run
Match (u:User)-[:Like*1..]->(m:Movie) return m
here m will be returned in order of the kind of design you chose ie either ascending order or descending order of the movie watched timestamp.

Resources