Neo4j Cypher query to find nodes with exact match (AND instead of OR) - nosql

I'm trying to create a query that bring me some node that have the exact match with a set of nodes. In this case I wanna bring experiences that have tags, for example, what experiences have tags: "food" AND "nightlife" AND "culture".
My query is "working", but bringing the result using OR instead of AND. How can I fix it?
I'm not sure if I'm using de correct approach of the
#Query("START experience = node:__types__(className=\"...\"), tags = node({0}) " +
"WHERE experience-[:TAGGED]->tags " +
"RETURN experience")
public Set<Experience> findExperiencesByTags(Set<Long> tagIds);
I'm using Spring Data 2.0.1 and neo4j 1.6.3.

try to divide it into 3 separate MATCH phrases:
"MATCH experience-[:TAGGED]->tags1, experience-[:TAGGED]->tags2, experience-[:TAGGED]->tags3, " +
"WHERE tags1.tag='food' AND tags2.tag='culture' AND tags3.tag='nightlife' "

I agree with #ulkas
If you really want to pass in an arbitrary number of tags you can try this, but it will probably perform not as good as the explicit matches.
START tags = node({0})
MATCH experience-[:TAGGED]->tags
WITH experience, count(*) as cnt
WHERE cnt = length({0})
RETURN experience

Related

jdbcTemplate query only executes with SELECT *

Long time lurker and learner, first time question here. I'm working a project for a local library to pull some data from their database to help the employees pull books put on hold for patrons. The catch here is the access to the database is read only. I cannot create any temporary tables or views.
We've created a long query to generate the data needed, I used a couple CTEs to whittle things down and then there's some logic based on which location the book may reside in to show where it should pick from. All in all, we're happy with the query results.
When I try to implement it using jdbcTemplate, I can't seem to find a way to get anything other than SELECT * to work.
WITH holdCTE1 (holdID, itemID, ...) AS (
SELECT *
FROM
table 1,
table 2,
table 3
WHERE
yada yada
This will give me results if I then do a SELECT * FROM holdCTE1.
If instead I specify columns, like this
WITH holdCTE1 (holdID, itemID, ...) AS (
SELECT t1.holdID, t2.itemID, t3.title
FROM
table 1,
table 2,
table 3
WHERE
yada yada
I get a syntax error at the first from table, regardless. I've tried adjusting all my table JOINs and using aliases and just about everything I can come across, but it doesn't seem to help.
A couple of things we're using to help the filtering and such, since we can't create a view to make it easy, is to call out the subqueries, so for example, in CTE1 we add a final column
'bib hold' AS hold_type
Even with the SELECT *, 'bib hold AS hold_type, I get the same syntax error. The actual wording of the error is:
StatementCallback; bad SQL grammar ... then my query ... nested exception is org.postgresql.util.PSQLException: ERROR: syntax error at or near ... the first thing under the FROM line
The library is using a Postgresql database, and I'm using Spring with jdbcTemplate for the SQL side.
Thanks in advance for looking.
Sorry for the poorly worded question, but I think I stumbled across an answer this evening. I was checking all of my queries I'd noted in pgAdmin, and I did a copy/paste into my java class.
With the escape characters, the code seems to run just fine. So this looks like it is passing info correctly to the query
WITH hold_bib (hold_id, item_id, birl_bib, patron, status, hold_type) AS (SELECT\n"
+ " h.id,\n"
+ " i.record_id,\n"
+ " birl.bib_record_id,\n"
+ " h.patron_record_id,\n"
+ " i.item_status_code,\n"
+ " 'bib'AS hold_type\n"
The function looks like this at the beginning now:
public List<Hold> libraryNotPicked() {
String sql = "\n"
+ "WITH hold_bib (hold_id, item_id, birl_bib, patron, status, hold_type) AS (SELECT\n"
+ " h.id,\n"
+ " i.record_id,\n"
+ " birl.bib_record_id,\n"
+ " h.patron_record_id,\n"
+ " i.item_status_code,\n"
+ " 'bib'AS hold_type\n"
...
+ " ;
List<Hold> holds = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Hold.class));
return holds;
Seems to me the key is the \n type characters in the query.

Is this kind of code prone to SQL injection?

I am doing a project for my school and I am task to debug all of the issues found using the application call HPE Fortify. The report generated by the application only indicates the code below prone to SQL injection:
String sql = " select Distinct p1.desc1,p2.desc2 from parameter p1"
+" inner join parameter p2"
+" on p1.ParaCode1='CR_DERIVE' and p1.ParaCode2=p2.Desc2"
+" inner join parameter p3"
+ " on p2.ParaCode3=p3.ParaCode1 and p3.ParaCode3=p2.Desc2"
+" where p2.paracode1='ATTRIBUTE'"
+ " and p2.ParaCode2='" + ddl_attribute.SelectedValue + "'";
But not the codes below:
strSQL = "SELECT Paracode2 FROM Parameter WHERE Paracode1 = 'PROGMGR' AND Desc1 = '" + login + "' AND Status = 'A' ";
I would like to know the reason why as I am unclear regarding SQL injection and I am new to this. Thanks for the response
You're concatenating some application variables into your SQL query string, so the safety depends on how those variables' values were set. Did they come from some untrusted input? Or were they set from some safe application data?
If HPE Fortify has analyzed your code and knows how your login variable was assigned its value, it may be able to tell that it's safe to use in an SQL expression. Whereas it may not be able to make that conclusion about the SelectedValue variable, so it assumes it's unsafe and therefore could cause an SQL vulnerability.
The Perl language does something similar, without the use of a tool like HPE Fortify. Every Perl variable is either "tainted" or "untainted" depending on where it got its value. So you can tell whether a variable is safe to use in SQL, or in eval() or other possible code-injection situations. It's a pity more languages don't support something similar.
But I agree with other commenters that you should learn to use query parameters. It's easy and it's safe. And you can stop getting eyestrain figuring out if you've balanced your quotes-within-quotes correctly.
Your code sample looks like it might be Java. Here's an example in Java:
strSQL = "SELECT Paracode2 FROM Parameter"
+ " WHERE Paracode1 = 'PROGMGR' AND Desc1 = ? AND Status = 'A' ";
Notice the ? placeholder for the parameter has no single-quotes around it within the SQL string. You must not put SQL quotes around the placeholder.
PreparedStatement stmt = con.PreparedStatement(sql);
stmt.setString(1, login);
ResultSet rs = stmt.executeQuery();
For more information to help you understand SQL injection, you might like my presentation SQL Injection Myths and Fallacies, or the video of me delivering that talk: https://www.youtube.com/watch?v=VldxqTejybk

ArangoDB AQL is affected by the injection issue?

I'm working with AQL in these days, and I'm creating a library for dynamically creating the AQL script.
Because I didn't find anything related to the PARAMETER INJECTION issue (like SQL INJECTION) do you think that is secure if I set my FILTER variable directly inside the AQL query string?
If you are using bindParameters for all user-defined input the value inserted will not be evaluated by the AQL parser and hence injected code will not be executed.
Safe query:
FOR x IN items FILTER x.name == #name RETURN x
Unsafe query:
"FOR x IN items FILTER x.name == " + name + " RETURN x"
Inserting sth. like
'a' LET t = (FOR h IN items DELETE h)
in name will return all elements having exactly this string in the save query (not harmful).
In the unsafe query it will drop all elements in items (harmful).

Satisfy this JPQL requirement

Requirement: The content of one string is present in the other. This tests on whole words only, but multi-word queries are allowed. For example, a query with givenName:Jane will match users with givenName values of "Jane" and "Jane Ann", but not "Janet". A multi-word query for givenName:Mary Ann would match values of "Mary Ann Evans" and "Sarah Mary Ann" but not "Ann Mary".
This is what I have so far.
I have a SiteRepository that extends the JpaRepository interface and it consists of the following method.
#Query("SELECT s from Site s WHERE s.name LIKE :givenName")
public List<Site> findByName(#Param("givenName") String givenName);
Now, the user is suppose to pass in a String value to the method below (for example ":Jane" or ":Mary Ann").
public List<Site> findByName(String givenName) //Where Site is an entity with a name field.
In the above method, I essentially check the first character of the parameter giveName to see if it is ":" and if it is, I substring givenName to cut out the colon and concatenate the following characters.
return siteRepository.findByName("%" + givenName.substring(1, givenName.length()) + "%"
+ " AND NOT LIKE _" + givenName.substring(1, givenName.length()) + "_");
So if I called, findByName(":Jane")
I should get the following JPQL query: SELECT s from Site s WHERE s.name LIKE %Jane% AND NOT LIKE _Jane_
This however does not work. Any help will be appreciated and thanks in advance.
I am not an expert in jpql, so I will write here only my assumptions which are not necessarily correct, but I try to help the op anyways.
If my answer is wrong, then please, leave a comment at the answer to let me know about it.
I think this answer does not deserve to be down-voted, as I have made clear that my answer is not necessarily correct and I will remove it if it is incorrect.
This was my idea described as a comment to the question without knowing the technical details:
You should write a query which checks whether all the words are
present and the first index of a word is before the last index of the
next word.
LOCATE(searchString, candidateString [, startIndex])
searches for the position of searchString in candidateString starting from startIndex, indexes being started from 1. The idea is to write a query which checks whether the locate returns other than 0 having a value of startIndex dependent of the startIndex of the previous string. (Source) If all your strings match the criteria, then the record should be included into the results.
I found a solution. This seems to work for the cases I tested so far.
" SELECT s FROM Site s WHERE s.name NOT LIKE 'Jane_' AND s.name NOT LIKE '_Jane' AND s.name NOT LIKE 'Jane' AND s.name LIKE '%Jane%' "

Lucene.net Fuzzy Phrase Search

I have tried this myself for a considerable period and looked everywhere around the net - but have been unable to find ANY examples of Fuzzy Phrase searching via Lucene.NET 2.9.2. ( C# )
Is something able to advise how to do this in detail and/or provide some example code - I would seriously seriously appreciate any help as I am totally stuck ?
I assume that you have Lucene running and created a search index with some fields in it. So let's assume further that:
var fields = ... // a string[] of the field names you wish to search in
var version = Version.LUCENE_29; // your Lucene version
var queryString = "some string to search for";
Once you have all of these you can go ahead and define a search query on multiple fields like this:
var analyzer = LuceneIndexProvider.CreateAnalyzer();
var query = new MultiFieldQueryParser(version, fields, analyzer).Parse(queryString);
Maybe you already got that far and are only missing the fuzzy part. I simply add a tilde ~ to every word in the queryString to tell Lucene to do a fuzzy search for all words in the queryString:
if (fuzzy && !string.IsNullOrEmpty(queryString)) {
// first escape the queryString so that e.g. ~ will be escaped
queryString = QueryParser.Escape(queryString);
// now split, add ~ and join the queryString back together
queryString = string.Join("~ ",
queryString.Split(' ', StringSplitOptions.RemoveEmptyEntries)) + "~";
// now queryString will be "some~ string~ to~ search~ for~"
}
The key point here is that Lucene uses fuzzy search only for terms that end with a ~. That and some more helpful info was found on
http://scatteredcode.wordpress.com/2011/05/26/performing-a-fuzzy-search-with-multiple-terms-through-multiple-lucene-net-document-fields/.