Searching in Neo4j - neo4j

My web application has users and Coworker relationship. I want to search users which has Coworker relationship with specific user. I used this query:
var query = _client
.Cypher
.Start(new
{
//user = Node.ByIndexLookup(IndexHelper.USER_INDEX, "Email", email)
}
).Match(String.Format("user-[:{0}]-(coworkers)", CoWorker.TypeKey))
.Where((User coworkers) => coworkers.Email.Contains(term))
.Return<Node<User>>("coworkers");
But It throws invalid parameter at
Where((User coworkers) => coworkers.Email.Contains(term)).
How can I replace this condition to search coworker with term? Thanks for reading.

Cypher doesn't actually support a contains operator like this, hence why the exception says there is no .NET equivalent.
The nearest you could do is use a regex:
WHERE coworkers.Email =~ ".*something.*"
But that would be horribly inefficient because you would run a regex across every node.

Related

Neo4j Python REST API

Query via Python REST-APi
message: Invalid input: ':'
Hello,
i am starting a query via my Python-Neo4j-Api.
But the code ist not working, resulting in the the error message above.
But the same query is working in the Neo4J Desktop App.
Why is it working in the Neo4j Desktop App, but not via my Api Query. Why is the : before param a Problem?
I am new to Python and Neo4j, please help.
King regards.
Trying to query via a Python-Neo4j-RestAPI.
Below is the syntax on passing parameters in neo4j python driver. Unfortunately, you cannot use labels or relationship types in the parameter. If you need to pass labels (like Human:Moviestar) then you can use string function in python like this: passing parameters in neo4j using python
name = "Tom Cruise"
placeOfBirth = "Syracuse, New York, United States"
query = "Create (n:Human:Moviestar { name: $name, placeOfBirth: $placeOfBirth})"
session = driver.session()
result = session.run(query, name=name, placeOfBirth=placeOfBirth)
I see that you have been working with the database though the browser application. So commands that are prefixed with ":" like :params or :connect are browser commands and is not valid cypher. Instead, in python pass your parameters as the second argument to your to your session.run() function or transaction. Then use variable substitution to in your cypher query.
params = {"name": "Tom Hanks" }
with driver.session as session:
result = session.run ("MATCH (p:person) where p.name = $name return p", params)

Filtering on "null" or "no values"

I am trying to make a filter in Graph API, querying for employees without phone, but with no luck.
This is a part of the query I am working on.
https://graph.microsoft.com/beta/users?$filter=userType eq 'Member'&$select = businessPhones
This results in something like this:
{ "businessPhones": ["+473456789"]},
{ "businessPhones": ["+479876543"]},
{ "businessPhones": ["+471234567"]}
What I am trying to do is ask for users without a businessphone
{ "businessPhones": []}
Something like this
https://graph.microsoft.com/beta/users?$filter=userType eq 'Member' and businessPhones eq ''
However, I have no clue on how to do this. Anyone?
EDIT, thanks Tiny Wang for pointing out "no filtering support":
businessPhones does not support filtering. However, assignedLicenses does. If I want to query for users without any assignedLicenses
{ "assignedLicenses" : [] }
How can I accomplish that?
Pls note, according to the api properity doc, businessPhones isn't a properity supporting $filter, see https://learn.microsoft.com/en-us/graph/api/resources/user?view=graph-rest-beta#properties
==========================UPDATE============================
Per my testing, I think it's also an unachievable task. It seems there're some 'defect' exists in ms graph OData filter. In this case, we need to use not assignedLicenses/any() according to OData protocol.
But according to my testing result, the query doesn't support using assignedLicenses/any()->Error: Complex query on property assignedLicenses is not supported , not assignedLicenses/any()->Error: Unsupported Query", but only support like assignedLicenses/any(x:x/skuId eq 3b555118-xxxx-e2096870).
What's more, when executing below query, it returns error Complex query on property assignedLicenses is not supported.
https://graph.microsoft.com/beta/users?$filter=userType eq 'Member' and assignedLicenses/any(x:x/skuId eq 3b555118-xxxx-2096870)&$select=assignedLicenses
But when executing this, it worked, so weird.
https://graph.microsoft.com/beta/users?$filter=assignedLicenses/any(x:x/skuId eq 3b555118-xxxxxx-df1e2096870)&$select=assignedLicenses
I also tried to use $count property to do the filter, but also failed:
I had the same task. After some research, I figured out how to filter out null string properties such as jobTitle, department, etc. Check this link.
Based on the answer, I tried the following query, and It works for me.
https://graph.microsoft.com/v1.0/users?$filter=NOT (businessPhones/any(p:p ge ' '))&$count=true
Be sure that you specified whitespace between quotes ' '.

Iterating 'forEach' member with a role

I have found several posts that seem to be trying to solve this problem, but none of the solutions / attempts I have seen will work for me.
I have a 'role' which my bot fetches successfully. On command I want the bot to then go through each of the members with that role and give them additional roles.
It simply will not work, so (for testing / debugging purposes) I currently have the following code:
const teamCaptainRole = await message.guild.roles.cache.find(role => role.name === "Team Captain");
console.log(teamCaptainRole.members)
await teamCaptainRole.members.forEach(member => {
console.log(member)
});
Previous 'console logs' of "teamCaptainRole" have shown me that I am successfully fetching the role. The console log of "teamCaptainRole.members" returns:
Collection [Map] {}
I have done googling around these words, but just find myself on a wild goose chase - I cannot find a way to dig down into this Map / Collection. I do not have any prior experience of working with maps, but arrays and objects I understand well. The 'forEach' never seems to trigger, but also doesn't throw any errors - simply nothing happens. Right now I would just love to be able to see a series of console logs of members that have that role so that I know the forEach is working.
Any help?
let role = message.guild.roles.cache.find(r => r.name === "Team Captain");
let giveRole = message.guild.roles.cache.find(r => r.name === "Enter Role Here");
let users = role.members.map(m => message.guild.member(m.user));
for(let user of users) {
user.roles.add(giveRole);
}
role -> The role where we will search the users from.
giveRole -> The role we will give all members that have role.
users -> The users who have role.
You could use users.forEach() as well but I used a basic for-loop. We map those users who have the role, but as an GuildMember Object, so that we can add giveRole in the for-loop.

How to search the group by the DisplayName using Microsoft Graph?

According to the document, I can list the Office 365 Groups by using the following Graph API:
GET https://graph.microsoft.com/v1.0/groups
I have a C# Web application, and there is a input for searching by the Group DisplayName. Any idea how to query groups based on the DisplayName?
I have tried the following URL: https://graph.microsoft.com/v1.0/groups?$search="displayName:Test" in the MS Graph Explorer which didn't work.
I get the following error.
{
"error": {
"code": "Request_UnsupportedQuery",
"message": "This query is not supported.",
"innerError": {
"request-id": "35d90412-03f3-44e7-a7a4-d33cee155101",
"date": "2018-10-25T05:32:53"
}
}
Any suggestion is welcomed.
Thanks in advance.
According to your description, I assume you want to search the Group by the DisplayName using the search parameters.
Based on this document, we can currently search only message and person collections. So we couldn't use the search parameter.
We can use the filter query parameter to search the Group by DisplayName. For example, we can search the groups whose displayName is start with 'Test',the request url like this:
https://graph.microsoft.com/v1.0/groups?$filter=startswith(displayName,'Test')
Here is C# code that I wrote to get a group using the DisplayName. This code requires a reference to the OfficeDevPnP.Core.
private static async Task<Group> GetGroupByName(string accessToken, string groupName)
{
var graphClient = GraphUtility.CreateGraphClient(accessToken);
var targetGroupCollection = await graphClient.Groups.Request()
.Filter($"startsWith(displayName,'{groupName}')")
.GetAsync();
var targetGroup = targetGroupCollection.ToList().Where(g => g.DisplayName == groupName).FirstOrDefault();
if (targetGroup != null)
return targetGroup;
return null;
}
UPDATE
I see that the answer has already been accepted, but I came across the same issue and found that this answer is out of date. For the next person, this is the update:
The 'search' functionality does work. Whether it was fixed along the way or always has, I am not sure.
'groups' support search,
both the v1 and beta api support search,
search only works on 'displayName' and 'description' fields,
searching on 'directory objects' require a special header: 'ConsistencyLevel: eventual'
Point number 4 is what tripped me up!
Your request would look like this:
https://graph.microsoft.com/v1.0/groups?$search="displayName:Test"
With the request header:
ConsistencyLevel: eventual
There is another catch: You can only specify the first 21 characters and the search always uses 'startsWith'. You're out of luck if you specify more than that: The search always fails.

How to make a regex to match all internet domains regardless of the extention

I need to a model validation to block personal email accounts.
I have the following:
PERSONAL_DOMAINS = %w[
yahoo.
ymail
verizon
]
The regex validation:
:format => {
:without => /#{PERSONAL_DOMAINS.map{|a| Regexp.quote(a)}.join('|')}/
}
The reason yahoo has a dot at the end is to allow yahoo-inc.com but block all the personal domains like yahoo.com, yahoo.fr, yahoo.uk etc...
This regex is failing and causing yahoo-inc.com to get rejected... Any suggestions on how this can be updated to make the use case above pass? Thanks
Try doing your match without Rails to help narrow down what's happening:
PERSONAL_DOMAINS_REGEXP = /#{PERSONAL_DOMAINS.map{|a| Regexp.quote(a)}.join('|')}/
=> /yahoo\.|ymail|verizon/
"yahoo-inc.com".match(PERSONAL_DOMAINS_REGEXP)
=> nil
"yahoo.com".match(PERSONAL_DOMAINS_REGEXP)
=> #<MatchData "yahoo.">
Try the following regex:
/(^|\.)(#{PERSONAL_DOMAINS.map{|a| Regexp.quote(a)}.join('|')})\.[^.]+$/i
This will match all domains whose second component is exactly one of the list.
so it will match:
yahoo.com
Yahoo.fr
sub.yahoo.id
etc, but not
yahoo-inc.com
notyahoo.com
yahoo.other.com
(change "yahoo." back to "yahoo")
Note also the "/i" at the end. domains are case-insensitive, so you will need this.

Resources