Improving query performance with many filtered aliases


(Kevin Mulvey) #1

tldr: queries with >40 filtered aliases take >1s, looking for a solution to support thousands of aliases with queries taking <1s.

Details:

  • Every document is indexed with an org_id.
  • Users can have access to many org_ids, up to 2100.
  • A filtered alias is created for each org_id (i.e. org_123), currently ~55k orgs
  • Currently have ~2M docs

Users send queries to an authorization service that acts as a transparent proxy to ES. It takes a token they provide and determines the list of orgs they have access to and runs their query by modifying the path with the ids. Example: http://host:9200/org_123,org_321,org_456,org_654/_search '{ user's query }'. This has worked fine for a small number of orgs (<40); in my testing, once you pass 40 orgs the queries take >
1s to complete. The test query was a match_all with 100 results.

Are filtered aliases the correct solution? Is there a better alternative? Should the data be indexed differently?

Thank you in advance.


(Nik Everett) #2

Maybe searching so many filtered aliases at once is causing trouble. A couple of things I'd check:

  1. Look at hot_threads while searching for >40 filtered aliases and have a look at what is going on.
  2. Manually translate the filtered alias into a terms query. terms queries are designed to find documents that contain one of many terms and see if that performs better.

From there you can decide though my instinct is that something is up with filtered aliases that is slowing you down. It might be just the query or something funny to do with filtered aliases I don't know about.


(Kevin Mulvey) #3

Thanks @nik9000, I tried both suggestions and converting my filter into a term query is a lot faster. I only tested it at 200 ids for now but that was ~400ms which is great. With regard to the original filtered alias, the reason I liked that was because my proxy didnt have to modify the user's query, just the path. My worry is that if I try to combine my new terms query with their query it may work some or most of the time but is bound to break as I dont have any idea what they will send.

I cant understand the output from the hot_threads so Ive pasted it below along with the original filter query.

{
"actions": [
    {
        "add": {
            "alias": "org_123",
            "filter": {
                "bool": {
                    "minimum_should_match": "1",
                    "should": [
                        {
                            "term": {
                                "org_id": "123"
                            }
                        },
                        {
                            "has_parent": {
                                "parent_type": "campaign",
                                "query": {
                                    "term": {
                                        "org_id": "123"
                                    }
                                }
                            }
                        }
                    ]
                }
            },
            "index": "indexone"
        }
    },
    {
        "add": {
            "alias": "demo",
            "index": "indexone"
        }
    }
]
}

hot threads: https://paste.fedoraproject.org/541848/85912925/


(Nik Everett) #4

I tend to be overly paranoid about has_parent. I try to build my indexes so I don't need parent/child because it is harder to reason about the performance. I'd try copy that org_id into whatever has the campaign parent just so you can use a single query there.

So right now you allow the user to search across multiple orgs, right? You just comma separate the list? That is fairly nice, yeah.

I wonder if it'd be a good idea to look into teaching elasticsearch how to recognize requests of this shape and build the terms query. In the case where you have this bool and has_parent going on I don't think it'd ever work, but rewriting a bool with a bunch of term queries into a terms query isn't that farfetched.


(Nik Everett) #5

The stack trace tells me that the has_parent query is taking up quite a bit of time. Probably, maybe. Reading these things is more an art than a science.


(system) #6

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.