I am currently working on a laravel application where users can add content like articles and those article are searchable via a search engine. I would like to implement a modern full text search solution. But the fact is it is possible for a user to put an article as private making it readable only by his followers or friends.
Implementing in simple SQL would be simple using a simple where clause on a pivot table relationship, but this is all but performant on large databases.
I made research's and devs on elastic search and other search engines but the limitation is that all the dataset is searchable and I cannot customize the filters according to a user defined relationship. Should I create one index per user instead of having a global index ? This seems to have a huge impact also
I would really appreciate any of your thought about this, thanks in advance.
CodePudding user response:
you can do this in Elasticsearch a few ways, that I can think of
- ideally use document level security as it's the most secure approach, but don't use filtered aliases with this
- add a boolean
private
field that you can then filter on. this is far less secure than DLS from above
if you've tried that second approach, then sharing what you did and what didn't work would help
CodePudding user response:
Try changing the perspective when looking at the problem.
Instead of thinking in terms of an article being accessible by certain groups of users, think in terms of a user and what articles she/he can access.
The search is always performed by a specific user, so it's known whom she/he follows (followed_user_ids
) and is friends with (friend_ids
). This information can be used at query build time.
The example query could look like this:
{
"query": {
"bool": {
"should": [
{
"term": {
"private": false
}
},
{
"bool": {
"filter": [
{
"term": {
"private": true
}
}
],
"should": [
{
"terms": {
"author_id": followed_user_ids,
}
},
{
"terms": {
"author_id": friend_ids,
}
}
],
"minimum_should_match": 1
}
}
]
}
}
}
It would find articles that:
- are not private (visible to all); or
- are private, but authored by friends or users followed by the current user