Azure Cosmos DB Graph Wildcard search - azure-cosmosdb

Is it possible to search Vertex properties with a contains in Azure Cosmos Graph DB?
For example, I would like to find all persons which have 'Jr' in their name?
g.V().hasLabel('person').has('name',within('Jr')).values('name')
Seems like the within('') function only filters values that are exactly equal to 'Jr'. I am looking for a contains. Ideally case insensitive.

None of the text matching functions are available for CosmosDB at this time. However, I was able to implement a wildcard search functionality by using a UDF (User Defined Function) which uses the Javascript match() function:
function userDefinedFunction(input, pattern) { return input.match(pattern) !== null; };
Then you'd have to write your query as SQL and use the UDF that you defined (the example below assumes you called you function 'REGEX'
SELECT * FROM c where(udf.REGEX(c.name[0]._value, '.*Jr.*') and c.label='person')
The performance will be far from ideal so you need to decide if the solution is acceptable or not based on your latency and cost perspectives.

The Azure team has now implemented Tinkerpop predicates for String
The Azure team has "announced" this to a user here on their feedback website.
I haven't tested all of them, but containing works for me (it is case sensitive though)
g.V().hasLabel('doc').or(__.has('title', containing('truc')), __.has('tags', containing('truc')))
TextP.startingWith(string)
Does the incoming String start with the provided String?
TextP.endingWith(string)
Does the incoming String end with the provided String?
TextP.containing(string)
Does the incoming String contain the provided String?
TextP.notStartingWith(string)
Does the incoming String not start with the provided String?
TextP.notEndingWith(string)
Does the incoming String not end with the provided String?
TextP.notContaining(string)
Does the incoming String not contain the provided String?

Related

Dynamic combination search on specific path in BaseX

I want to perform dynamic combination (AND OR) search on the basis of the provided parameter by the user.
Search Combination Example:
( (title = "United States" or isbn = "2345371242192") and author ="Jhon" )
In the above query each parameter will look on their XPATH e.g. (item/tigroup/title, item/isbn), XPATH not provided by the user, i have to generate XPATH dynamically with search combination
How Combination query can be formed dynamically to pass it to the BaseX?
User can perform any kind of AND OR search, their can be multiple AND OR criteria
Any suggestions much appreciated
With xquery:eval, strings can be evaluated as XQuery expression (see the documentation for more examples):
declare variable $QUERY := 'text()';
db:open('db')//*[xquery:eval($QUERY, map { '': . })]
Please note that it’s very risky to evaluate arbitrary strings as XQuery code. If the string contains user input, malicious strings may be passed on that do unexpected things. In the example above, a malicious string could be a file operation (e.g., file:delete(.)), or a query that runs very long and blocks your system.

Gremlin code to find 1 vertex with specific property

I want to return a node where the node has a property as a specific uuid and I just want to return one of them (there could be several matches).
g.V().where('application_uuid', eq(application_uuid).next()
Would the above query return all the nodes? How do I just return 1?
I also want to get the property map of this node. How would I do this?
You would just do:
g.V().has('application_uuid', application_uuid).next()
but even better would be the signature that includes the vertex label (if you can):
g.V().has('vlabel', 'application_uuid', application_uuid).next()
Perhaps going a bit further if you explicitly need just one you could:
g.V().has('vlabel', 'application_uuid', application_uuid).limit(1).next()
so that both the graph provider and/or Gremlin Server know your intent is to only next() back one result. In that way, you may save some extra network traffic/processing.
This is a very basic query. You should read more about gremlin. I can suggest Practical Gremlin book.
As for your query, you can use has to filter by property, and limit to get specific number of results:
g.V().has('application_uuid', application_uuid).limit(1).next()
Running your query without the limit will also return a single result since the query result is an iterator. Using toList() will return all results in an array.

How to do a Case Insensitive search on Azure DocumentDb?

is it possible to perform a case insensitive search on DocumnetDb?
Let's say I have a record with 'name' key and value as "Timbaktu"
This will work:
select * from json j where j.name = "Timbaktu"
This wont:
select * from json j where j.name = "timbaktu"
So how do yo do a case insensitive search?
Thanks in advance.
Regards.
There are two ways to do this. 1. use the built-in LOWER/UPPER function, for example,
select * from json j where LOWER(j.name) = 'timbaktu'
This will require a scan though. Another more efficient way is to store a "canonicalized" form e.g. lowercase and use that for querying. For example, the JSON would be
{ name: "Timbaktu", nameLowerCase: "timbaktu" }
Then use it for querying like:
select * from json j WHERE j.nameLowerCase = "timbaktu"
Hope this helps.
Cosmos recently added a case-insensitive option for string functions:
You now have an option to make these string comparisons
case-insensitive: Contains, EndsWith, StringEquals, and StartsWith.
and Significant performance improvements have been realized for these
string system functions. Each of these four string system functions
now benefit from an index and will therefore have much lower latency
and request unit (RU) consumption.
Announcement
Perhaps this is an ancient case, I just want to provide a workaround.
You could use UDF in azure cosmos db.
udf:
function userDefinedFunction(str){
return str .toLowerCase();
}
And use below sql to query results:
SELECT c.firstName FROM c where udf.lowerConvert(c.firstName) = udf.lowerConvert('John')

How to encrypt a Huge query string to in short

I have a huge query string which is around 6000 to 7000 characters, is it possible to encrpyt the string in short?
any alogrithms ?
Usign ASP.NET as the web app.
The short answer is don't do it - it probably indicates you are doing something wrong.
If you have to then I would say the best way would be to store the long query string in a database field and generate a Guid you can store as a key against it.
You can then pass the Guid in the query string and when the page loads you can then retrieve the full details from the database using the key.
The URL accepts 255 character, after that you'll get nothing.
Use what Mr. Kevin mentioned, database storage, or use the context session to store variables you are sending in the query string.

Understanding HQL queries on collection objects

This is similar to a question I asked earlier. The answers to that question partially solved my issue, but I'm still having some issues in trying to perform the kind of search I specified there; furthermore, I'm simply having trouble understanding how Hibernate chooses what to return in different scenarios.
Here's my mapping:
Client {
#OneToMany(mappedBy="client",cascade=CascadeType.ALL)
private Set<Group> groups = new HashSet<Group>();
}
Group {
#ManyToOne (cascade=CascadeType.ALL)
private Client client = new Client();
private String name;
private String state; //two char state code
private String extId; //unique identifier; candidate key, but not the #Id.
}
Queries by name are inline (e.g., like with wildcards on both ends of the param); state and extId are by equality.
The following query returns a single client, with only the matching group attached, even if other groups are associated to the client (note again that extId will only return one group):
select distinct client from Client as client
inner join client.groups as grp
where grp.extId = :extId
This query returns a single client, but with all associated groups attached, regardless of whether the group's state code matches the criteria:
select distinct client from Client as client
inner join client.groups as grp
where grp.state= :state
Finally, this query returns a separate copy of the client for each matched group, and each copy contains all of its associated groups, regardless of whether the group's name matches the criteria:
select distinct client from Client as client
inner join client.groups as grp
where grp.name like :name
I'm new to Hibernate, and I'm finding it immensely frustrating that I'm unable to predict what is going to be returned from a given query. All three queries are nearly identical, except for some small changes in the WHERE clause, yet I get radically different results for each. I'd spent time reviewing the documentation, but I'm missing wherever this behavior is explained. Can anyone help shed some light on this?
Finally, what I really need to do is to return Clients when querying by Group, and have the client only contain the Groups which match the search criteria. Is there a single-shot way I can construct an HQL query to do so, or will I have to do multiple queries and build my objects up in code?
Thanks.
The answer to this is twofold. One, there was a problem with the test harness, which was (sensibly) using transaction rollback to create test instances without leaving artifacts in the database. This was the source of my odd responses in the queries.
I managed to return just the values I wanted in the collections by simply changing to an outer fetch join.

Resources