I want to filter my application users based on their phone number or email, but I don't want exact match, instead part of the email or part of the number users should return in response. Is there a way in Quickblox iOS SDK?
Suppose, I've some quickblox users like below :
ID NAME Email Address Mobile Number
User1 | yuyuqabc#somedomain.com | +91-12345-67890
User2 | qerqrorp#somedomain.com | +1-123-000-7891
User3 | xyzabcqry#somedomain.com | +64-123-456-78
Now the filter should apply like this,
if I want to query on email, which contains "abc" then should return 1st and 3rd user.
if I want to query on phone number, which contains "23" then should return all users.
if I want to query on phone number, which contains "234" then should return 1st and 3rd user.
Is it possible?
It is possible only if you will use CustomObjects module instead of Users.
So you will need to create User class in CustomObjects and you will have all operators working there.
In Users it is impossible.
Related
If I want to query a list of users, I want to dynamically pass in the parameters, for example, can only query according to username, or according to the combination of username and userType conditions to query, I do not know how to use typeORm to write
I guess what you are looking for is find options. Link to official documentation: TypeORM - Find Options
repository.findOne(id?: string | number | Date | ObjectID, options?: FindOneOptions<Entity>): Promise<Entity | undefined>;
findOne function takes in two parameters. First one defines logic to how you want the record to find, by id or its column value. Second parameter lets you fetch the relations if you have any with the specific entity.
SendBird treats every channel as their GroupChannel. The 1:1 chat too is technically a GroupChannel with only two users (with isDistinct = true so it would return the personal chat when you attempt to create it again).
My question is, how do I search GroupChannels by their name those include group AND 1:1 chat? The group chat would have a common name that would be shown to all the users in the group. But for 1:1 chat, the GroupChannel won't have a name, and if it has, that won't be shown to the users as for 1:1 chat, we always show the other person's name (like almost all the chat systems work).
Typically the main UI list contains mixture of the group chat and 1:1 chats (all the GroupChannels).
--------------------------------
| Search Chat TextField |
|--------------------------------|
|1 John (1:1) |
|2 John's Birthday Plan (group) |
|3 Johnney Eve (1:1) |
|4 Johansson Fans (group) |
| ... |
--------------------------------
All the items are technically GroupChannel. Note that all the 1:1 chats don't have actual name as shown in the list. The name shown in the list is the other person's nickname.
Expectation:
Now, if the user searches something like "joh", then it should return all the group chats whose name contains "joh" OR all the 1:1 chats where the other person's name contains "joh". (Basically all the items shown in the above example.)
My Attempt:
My initial solution to achieve this is to keep the 1:1 channel name as <user1 nickname> & <user2 nickname>, so when the user searches for the other user by their name, the 1:1 channel would appear just like a group channel.
Example Code:
query = SBDGroupChannel.createMyGroupChannelListQuery()
query?.order = .latestLastMessage
query?.limit = 30
query?.channelNameContainsFilter = "joh"
query.loadNextPage(...)
The Problem:
The problem with this are:
If the user searches for their own name (or just the separator character & or just a whitespace), then too all the personal chat would be visible, which is irrelevant.
My system allows user to change their nickname, so every time a user changes their nickname, then all the 1:1 channel names have to be updated (which is painful).
Sunil,
Typically when you retrieve a list of group channels for a user, it retrieves all channels that the user is potentially a part of (Depending on the memberStateFilter).
If you were explicitly looking to search, rather than providing an ongoing list of channels the user is part of, you may be able to filter channels by userIds. You'd have to filter for a channel that consists of the searching user, and the desired user.
Lets look at an example, assuming your userId is John and you're looking for your chat with Jay:
let listQuery = SBDGroupChannel.createMyGroupChannelListQuery()
listQuery?.userIdsExactFilter = ["John", "Jay"]
listQuery?.loadNextPage(completionHandler: { (groupChannels, error) in
guard error == nil else {
// Handle error.
}
// Only channelA is returned in a result list through the "list" parameter of the callback method.
...
})
If you wanted to explicitly use nicknames:
let listQuery = SBDGroupChannel.createMyGroupChannelListQuery()
listQuery?.nicknameContainsFilter = ["John", "Jay"]
listQuery?.loadNextPage(completionHandler: { (groupChannels, error) in
guard error == nil else {
// Handle error.
}
// Only channelA is returned in a result list through the "list" parameter of the callback method.
...
})
You mention that you allow users to change their nicknames, and thus rooms have to be updated. It may be worth giving your group channels (even 1:1) generic names, and then dynamically generate the display name of each chat.
Since each channel returns the list of members, you could look at the array of members, filter out the user that is logged in, and then pull the nickname of the remaining user from the array. This would ensure that no matter what the user changes their nickname to, its always accurate, and you don't have to update every channel when the user updates their nickname.
************ Updated 02/10 ************
Thanks for providing an example of what you're looking to achieve. It looks like you're essentially trying to search both channelNameContainsFilter and nicknameContainsFilter using the OR operator. This is not something we (Sendbird), currently support within the iOS SDK. So the question is, what could you do to achieve this?
One option would be to utilize the Platform API to obtain this information. The List my group channels has the search_query and search_fields parameters which would allow you to utilize that OR operator to find both channel names and nicknames that match your value.
Alternatively, since the SDK does return all of the necessary data that would be required to filter for these results, you could create a front-end filter that would only display the items that match your filter results. So the SDK returns the complete channel list, you store that list, and then when the user searches, you filter through the list to find channels that match your needs and display only those.
As a side note, Stackoverflow may not be the best place for this type of discussion as there is a lot of back and forth. Please feel free to join us in our community for more support.
Here's the scenario. I'm trying to create an inbox of the most recent (multi message) conversations between users in which the most recent message (sent OR received) has a brief preview in the listing.
(as an aside I'm aware of the post UNION filtering issue that's open: https://github.com/neo4j/neo4j/issues/2725) but I'm not sure if my question is fully answered by that.
Let's imagine it displays like this:
User 1's inbox:
user03 - "hey hows it going I..."
user02 - "yo user 2, I saw wh..."
user04 - "did you know I foun..."
user26 - "dear user01 I just ..."
In the graph database conversations are represented with this relationship:
(:User)<-[s:SENDER]-(m:Message)-[r:RECEIVER]->(:User)
Matching this and ordering by m.created_at gets you conversations.
I can easily find messages between specific users and I can easily find all messages that include a given user such as in the following query (given a username of "brendanh":
MATCH (u:User)<-[s:SENDER]-(m:Message)-[r:RECEIVER]->(u2:User)
WHERE (u.username = "brendanh") OR (u2.username = "brendanh")
RETURN m.body, u.username as sender, u2.username as receiver ORDER BY m.created_at DESC
Obviously that previous query gets me ALL messages from or to "brendanh"
Example result rows:
body sender receiver
blah blah blah brendanh user2
foo foo foo user3 brendanh
bar bar bar user2 brendanh
test test brendanh user4
i do not know user3 brendan
Where as what I want is this:
body sender receiver
blah blah blah brendanh user2
foo foo foo user3 brendanh
test test brendanh user4
I can get just a set of unique conversational participants with the following:
MATCH (u:User {username:'brendanh'})<-[]-(m:Message)-[]->(u2:User)
return distinct(u2.username)
But it's not like I can take that list of single usernames and do a "For" match on it returning the first message match for each. (Within the cypher query I mean)
I could collect that list of conversational participants (I'm running this in Golang) and then run a query to the graphdb for each individual result but that seems messy.
I've tried using UNWIND and a list of the usernames from that previously described query that listed conversational partners but again I get every message not just the first message for each user.
Is there something extremely obvious I'm missing here?
Any help is appreciated, thanks!
P.S. Ideally I'd like to limit the number of responses such that if I want to display only the first ten results assuming the user has >10 conversations but that's less important
Not so easy to understand what you want, but I think I got it.
You want each partner to only occur once in the list with their first? message.
Perhaps like this:
MATCH (u:User)<-[r:SENDER|:RECEIVER]-(m:Message)-[:SENDER|:RECEIVER]->(u2:User)
WHERE (u.username = "brendanh")
WITH u2,m,type(r) as action ORDER BY m.created_at DESC
WITH u2,head(collect({type:type(r), msg: m})) as conv
RETURN u2.username, conv.msg.body, conv.type
I currently have the following cypher to return a list of Users, with the Roles they are assigned and the Application that the Role is for.
MATCH (u:User)-[:HAS_ROLE]->(r:Role)-[:ROLE_OF]->(a:App)
RETURN u as User, COLLECT([r, a]) as Roles
This returns a User and a collection of their roles and apps, but the collection is simply [roleA, appA, roleB, appA, roleC, appB...].
Is there any way to return something like [[roleA, appA], [roleB, appA], [roleC, appB]...] as processing this list on the assumption that it is role, app, role, app does not seem like good practice to me.
I can return the roles and apps as separate collections, but then I do not know which app each role is assigned to.
The only other way I can think of doing this is to perform multiple queries, which I do not want to do.
I am sure there must be a better way, maybe using WITH, but I am new to Cypher.
Many thanks for your help :)
You query appears to be working for me.
http://console.neo4j.org/r/4zp6uv
The output is:
+--------------------------------------------------------------------------------------------------------+
| User | Roles |
+--------------------------------------------------------------------------------------------------------+
| Node[5]{name:"u1"} | [[Node[4]{name:"r1"},Node[2]{name:"a1"}],[Node[3]{name:"r2"},Node[1]{name:"a2"}]] |
+--------------------------------------------------------------------------------------------------------+
1 row
14 ms
If you are still having some issues for some reason or another you could try modifying the query slightly just to break it up.
MATCH (u:User)-[:HAS_ROLE]->(r:Role)-[:ROLE_OF]->(a:App)
WITH u, [r, a] as tuple
RETURN u as User, COLLECT(tuple) as Roles
I'm using Parse.com, and have two classes: User and Report. A User may issue several reports during a day, but I'm only interested in the most recent one. However, I need to get all the reports that meet specific criteria, but only the most recent one.
The end result is an array of Reports, where the User is unique on each one, something like this:
ObjectId | ReportedValue | User | CreatedAt
1234 | 100 | aaaa | 2013-05-20T04:23:41.907Z
1235 | 100 | bbbb | 2013-04-29T05:10:41.907Z
1236 | 100 | cccc | 2013-05-20T02:14:41.907Z
1237 | 100 | dddd | 2013-05-19T04:03:41.907Z
So, User aaaa might have 20 reports, but I only need the most recent, for each user. However, I'm searching based on the ReportedValue being 100, and the desired result is the report objects, not the user, so I'd prefer not to go through every user.
Is this possible in Parse?
Consider using another object in the data model to assist with this. It would basically be a container with a relationship to Report. When any new report is saved, a bit of cloud code runs which:
Finds the previous latest Report for the associated user
Removes that report from the container relation
Adds the new report to the container relation
Working this way, your app can make a single, simple, query on the relation to get all of the latest Reports.
From Rest API.... works providing the user's OID is in the ACL segment in the records in the Class you are querying.
in addition to the other predicate of your query, parse can limit the number of returned rows..
--data-urlencode 'limit=1' \
--data-urlencode 'skip=0' \
For the user, if you GET the row from user table for the user you are querying
and the 'token' field value for that user and then with your report query, Set an extra header to the sessionToken value you will get ONLY THAT User's report objects.
-H "X-Parse-Session-Token: pn..." \
you will get just that user's reports
AND
results.size = 1