Neo4j - How to formulate this query using executeCypher using params - lucene

I have a query like this
start n = node:node_auto_index('ids:"123", "456" ... ') return n
Here 123, 456 is a list of keys as a single param {list}. Now when I try to write this in Java
String q = " START n=node:node_auto_index('key:{ids}') return n "
Map<String, Object> map = new HashMap<String, Object>();
map.put("ids", keyList); // keyList is a list of strings
But somehow calling graphstoreclient.executeCypher(q, map) fails with parse error, can you point me to any documentation / correct syntax on this.
PS - This query works fine on console.

Since you're supplying a lucene query string, parameterize the entire string:
String q = " START n=node:node_auto_index({ids}) return n "
Map<String, Object> map = new HashMap<String, Object>();
map.put("ids", keyList);
keyList should now look like ids:"123", "456" ...

Related

Order of the iterations of entries in an Ignite cache and seek method

What is the ordering of the keys in an Ignite cache (without using indexing) and is it possible to do the equivalent of the following RocksDB snippet
try (final RocksIterator rocksIterator =
rocksDB.newIterator(columnFamilyHandleList.get(1))) {
for (rocksIterator.seek(prefixKey);
i.e. jump to the next entry starting with a given byte[] or String?
The way you'd do that in Ignite is by using SQL.
var query = new SqlFieldsQuery("select x,y,z from table where z like ? order by x").setArgs("prefix%");
try (var cursor = cache.query(query)) {
for (var r : cursor) {
Long id = (Long) r.get(0);
BigDecimal value = (BigDecimal) r.get(1);
String name = (String) r.get(2);
}
}

Using Apache Velocity for template SQL

I want to use Apache Velocity Template Engine to generate SQL query based on the input.
Any sample snippet to get started would be helpful.
JSONObject keysObject = new JSONObject();
keysObject.put("HistoryId", "1");
keysObject.put("TenantName", "Tesla");
Iterator<?> keys = keysObject.keys();
ArrayList list = new ArrayList();
Map map = new HashMap();
while( keys.hasNext() ) {
String key = (String)keys.next();
map.put(key, keysObject.get(key));
}
list.add( map );
int keyObjectSize = keysObject.length();
JSONObject can have more keys, but in this example i am using 2.
I want to use the keys historyId and tenantName to generate below SQL query, Where keys are used as the column name and keys size can be used to generate the value parameter(?1, ?2).
INSERT INTO "Alert" (historyid, tenantname) VALUES (?1, ?2)

Lucene.Net SynonymFilter with multiple word phrases

I am using Lucene.net and am trying to implement a SynonymFilter to provide expanded terms when items within my database of products can be named differently, or spelled differently - e.g. "spanner" > "wrench", or "lawnmower" > "lawn mower".
As a test I setup a SynonymMap as follows :
String base1 = "lawnmower";
String syn1 = "lawn mower";
String base2 = "spanner";
String syn2 = "wrench";
SynonymMap.Builder sb = new SynonymMap.Builder(true);
sb.Add(new CharsRef(base1), new CharsRef(syn1), true);
sb.Add(new CharsRef(base2), new CharsRef(syn2), true);
SynonymMap smap = sb.Build();
Searching for "spanner" or "wrench" brings back all terms with either word in. Searching for "lawn mower" or "lawnmower" only brings back terms that match exactly the input search criteria.
Is there something else that needs to done for multiple word phrases within the Synonyms?
Also how do I expand to say 3 or more terms for for example "lawnmower", "lawn mower", "mower", "grass cutter"?
Thanks
There is an example of multi-word synonyms in the unit tests. You have to split the words yourself and insert a SynonymMap.WORD_SEPARATOR (null character) between them. To make this easier, there is a Join method on SynonymMap.Builder.
String base1 = "lawnmower";
String syn1 = "lawn mower";
SynonymMap.Builder sb = new SynonymMap.Builder(true);
CharsRef syn1Chars = sb.Join(Regex.Split(syn1, " +"), new CharsRef());
sb.Add(new CharsRef(base1), syn1Chars, true);
SynonymMap smap = sb.Build();
Here is an extension method to make quick work of this.
public static class SynonymMapBuilderExtensions
{
private static Regex Space = new Regex(" +", RegexOptions.Compiled);
public static void AddPhrase(this SynonymMap.Builder builder, string input,
string output, bool keepOrig)
{
CharsRef outputRef = builder.Join(Space.Split(output), new CharsRef());
builder.Add(new CharsRef(input), outputRef, keepOrig);
}
}
You can then use this extension method whether the synonym has spaces or not, and you don't have to bother with creating the CharsRef objects if you don't need them anywhere else in your code.
String base1 = "lawnmower";
String syn1 = "lawn mower";
String base2 = "spanner";
String syn2 = "wrench";
SynonymMap.Builder sb = new SynonymMap.Builder(true);
sb.AddPhrase(base1, syn1, true);
sb.AddPhrase(base2, syn2, true);
SynonymMap smap = sb.Build();

How to call Oracle's regexp_like function with Nhibernate QueryOver?

I'm aware I need to use Restrictions.Eq and Projections.SqlFunction, but I've been trying for hours without any success (my test app just crashes). Does anyone have an QueryOver example that would do the following in Oracle:
SELECT
*
FROM
V_LOG_ENTRIES
WHERE
regexp_like(ENTRY_TEXT, '(\WPlaced\W)');
UPDATE: Okay, I think part of the problem is that Restrictions.Eq expects an equality, but there is no equality in this case, it's just a function call in the WHERE clause...
The syntax should be like this:
// this is inlined string, but could be concatenated from some params
var sql = #" regexp_like(ENTRY_TEXT, '(\WPlaced\W)') " +
" AS isLike";
var sqlString = new SqlString(sql);
// the ICriterion
var criterion = new NHibernate.Criterion.SQLCriterion(sqlString
, new string[] {}
, new IType[] {}
);
// the query
var query = session.QueryOver<LogEntry>()
.Where(criterion)
...

Does Dapper support the like operator?

Using Dapper-dot-net...
The following yields no results in the data object:
var data = conn.Query(#"
select top 25
Term as Label,
Type,
ID
from SearchTerms
WHERE Term like '%#T%'",
new { T = (string)term });
However, when I just use a regular String Format like:
string QueryString = String.Format("select top 25 Term as Label, Type, ID from SearchTerms WHERE Term like '%{0}%'", term);
var data = conn.Query(QueryString);
I get 25 rows back in the collection. Is Dapper not correctly parsing the end of the parameter #T?
Try:
term = "whateverterm";
var encodeForLike = term => term.Replace("[", "[[]").Replace("%", "[%]");
string term = "%" + encodeForLike(term) + "%";
var data = conn.Query(#"
select top 25
Term as Label,
Type,
ID
from SearchTerms
WHERE Term like #term",
new { term });
There is nothing special about like operators, you never want your params inside string literals, they will not work, instead they will be interpreted as a string.
note
The hard-coded example in your second snippet is strongly discouraged, besides being a huge problem with sql injection, it can cause dapper to leak.
caveat
Any like match that is leading with a wildcard is not SARGable, which means it is slow and will require an index scan.
Yes it does. This simple solution has worked for me everytime:
db.Query<Remitente>("SELECT *
FROM Remitentes
WHERE Nombre LIKE #n", new { n = "%" + nombre + "%" })
.ToList();
Best way to use this to add concat function in query as it save in sql injecting as well, but concat function is only support above than sql 2012
string query = "SELECT * from country WHERE Name LIKE CONCAT('%',#name,'%');"
var results = connection.query<country>(query, new {name});
The answer from Sam wasn't working for me so after some testing I came up with using the SQLite CONCAT equivalent which seems to work:
string sql = "SELECT * FROM myTable WHERE Name LIKE '%' || #NAME || '%'";
var data = IEnumerable data = conn.Query(sql, new { NAME = Name });
Just to digress on Sam's answer, here is how I created two helper methods to make searches a bit easier using the LIKE operator.
First, creating a method for generating a parameterized query, this method uses dynamic: , but creating a strongly typed generic method should be more desired in many cases where you want static typing instead of dynamic.
public static dynamic ParameterizedQuery(this IDbConnection connection, string sql, Dictionary<string, object> parametersDictionary)
{
if (string.IsNullOrEmpty(sql))
{
return null;
}
string missingParameters = string.Empty;
foreach (var item in parametersDictionary)
{
if (!sql.Contains(item.Key))
{
missingParameters += $"Missing parameter: {item.Key}";
}
}
if (!string.IsNullOrEmpty(missingParameters))
{
throw new ArgumentException($"Parameterized query failed. {missingParameters}");
}
var parameters = new DynamicParameters(parametersDictionary);
return connection.Query(sql, parameters);
}
Then adding a method to create a Like search term that will work with Dapper.
public static string Like(string searchTerm)
{
if (string.IsNullOrEmpty(searchTerm))
{
return null;
}
Func<string, string> encodeForLike = searchTerm => searchTerm.Replace("[", "[[]").Replace("%", "[%]");
return $"%{encodeForLike(searchTerm)}%";
}
Example usage:
var sql = $"select * from products where ProductName like #ProdName";
var herringsInNorthwindDb = connection.ParameterizedQuery(sql, new Dictionary<string, object> { { "#ProdName", Like("sild") } });
foreach (var herring in herringsInNorthwindDb)
{
Console.WriteLine($"{herring.ProductName}");
}
And we get our sample data from Northwind DB:
I like this approach, since we get helper extension methods to do repetitive work.
My solution simple to this problem :
parameter.Add("#nomeCliente", dfNomeCliPesquisa.Text.ToUpper());
query = "SELECT * FROM cadastrocliente WHERE upper(nome) LIKE " + "'%" + dfNomeCliPesquisa.Text.ToUpper() + "%'";