问题
Problem: Use Amplify.js from AWS. A Tinder similar app. Here you can find jobs close by. These may only be seen once. We should save what the user likes and dislikes.
What I've already managed:
I have the scheme:
type Query {
nearbyJobs(location: LocationInput!, km: Int): ModelJobConnection
}
type User @model {
id: ID!
name: String
interacts: [Jobinteract] @connection(name: "interactsuser")
createdAt: String
updatedAt: String
}
type Job @model @searchable {
id: ID!
name: String
location: Location
is_swiped_by: AWSJSON
interacts: [Jobinteract] @connection(name: "interactjob")
createdAt: String
updatedAt: String
}
With @searchable I have established the connection to ElasticSearch. Since this seems to be the only way to search for jobs nearby.
Now it becomes tricky.
At the moment I save in the field: is_seen_from_user all users id´s who have already seen this job. Since there were about 1000 users so far, that was ok.
This was my es query:
"body": {
"size": 30,
"sort": [
{
"createdAt": {
"order": "desc"
}
}
],
"query": {
"bool": {
"must": [
{
"range": {
"createdAt": {
"gte": "now-30d/d"
}
}
}
],
"must_not": {
"match_phrase": {
"is_swiped_by.user": "$ctx.identity.sub"
}
},
"filter": {
"geo_distance": {
"distance" : "${distance}km",
"location" : $util.toJson($ctx.args.location)
}
}
}
}
is_swiped_by.user So I looked into the array to see if the user was there. if yes - skip.
But now I rather have the problem that there can be more users.
This means, I can't save it into a field anymore. There would probably have to be a new table.
type Jobinteract @model {
id: ID!
user: User! @connection(name: "interactsuser")
job: Job! @connection(name: "interactjob")
decision: Int
createdAt: String
updatedAt: String
}
The question now is. If I have the table (Jobinteract) now. Should I make it @searchable too?
Then I also have the data in ElasticSearch. But how can I bring them together? It is then data from different indexes.
I read hasChild in ES. But don't understand exactly how this should work, if it's the right way?!
i'm also currently testing whether i can get access to ES via a lambda, so i'd just call up all the jobs nearby and compare them myself. But that's probably not the best option. Get 100 jobs from nearby from Elasticsearch, compare it to the table below. If there are 50 left, send them to the frontend, if not, get 100 again. The more the user liked, the longer this call would go.
回答1:
The @searchable directive does not currently support custom ElasticSearch mappings out of the box so you will need to perform some custom setup for your ElasticSearch cluster. You should be able to use joining queries such as hasChild to find all locations where there is no associated child record in the same index that indicates the user has interacted with the job before.
As of writing, the @searchable directive stores different @models in separate indexes so you will need to write a custom resolver that puts the "Interaction" child record in the same index that specifies when a user has interacted with a job and then you will need to update the ES index mapping such that it uses a join data type so you can use the hasChild query. See https://www.elastic.co/guide/en/elasticsearch/reference/current/parent-join.html for more information.
来源:https://stackoverflow.com/questions/56430019/how-to-get-unseen-nearby-documents-from-a-amplify-appsync-elasticsearch-d