Query Multiple Indexes, but apply queries to specific index

I am querying two indexes. They both have the same field. I want to apply one of my queries to one of the indexes and not both.

Here's an extremely basic example that represents what I'm trying to do:

PUT places
{
  "mappings": {
    "doc": {
      "properties": {
        "zip": {
          "type": "text"
        }
      }
    }
  }
}

PUT people
{
  "mappings": {
    "doc": {
      "properties": {
        "name": {
          "type": "text"
        },
        "zip": {
          "type": "text"
        }
      }
    }
  }
}

PUT places/doc/1
{
  "zip":"44645"
}

PUT people/doc/1
{
  "name": "Bob",
  "zip":"44645"
}


GET /places,people/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "zip": {
              "_name": "Match Place Only",
              "query": "44645"
            }
          }
        },
        {
          "match": {
            "name": {
              "_name": "Match Person Only",
              "query": "bob"
            }
          }
        }
      ]
    }
  }
}

The query for for "zip" is being applied to both indexes, when I really only want it to go against the Places index.

I'm using index aliases on my real index (not in this example) in v6.2.3.

You could combine each of your queries with a filter on the _index field. Like this:

GET /places,people/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "bool": {
            "_name": "Match Place Only",
            "must": [
              {
                "match": {
                  "zip": {
                    "query": "44645"
                  }
                }
              }
            ],
            "filter": {
              "term": {
                "_index": "places"
              }
            }
          }
        },
        {
          "bool": {
            "_name": "Match Person Only",
            "must": [
              {
                "match": {
                  "name": {
                    "query": "bob"
                  }
                }
              }
            ],
            "filter": {
              "term": {
                "_index": "people"
              }
            }
          }
        }
      ]
    }
  }
}

Thanks for the suggestion. This seems a bit intense when I have several match queries going on. Suppose I could make it work.

The bigger issue with this suggestion is that the _index field for term queries currently doesn't support index aliases.

Maybe you can do a multi-search instead? This is a way of sending multiple queries in a single request. You could send separate queries to each of the indexes/aliases you want to query:

GET _msearch
{"index": "places" }
{"query":{"match":{"zip":{"_name":"Match Place Only","query":"44645"}}}}
{"index": "people"}
{"query":{"match":{"name":{"_name":"Match Person Only","query":"bob"}}}}

You won't get a single set of hits, but a separate set of hits for each query. However, this may good enough for what you're trying to do?

1 Like

I'm basically trying to return search results for Companies or Contacts from one search box. I need the results to be intermingled (as the scores allow) in order to allow the best company and contact matches to rise to the top.

I considered using multi-search and even played around with it.
It seemed like there was more support for using a Bool Query across multiple indexes and I honestly wasn't sure about how the scoring worked. Are the scores calculated differently when two indexes are queried together (bool query) vs when they're queried separately (msearch query)??

At this point I will probably just try to make the bool query work. I'm fairly new to ES and have a strong relational database background, so the ability to query across indexes without the ability to easily limit to one index or the other has me scratching my head.

Yeah, Elasticsearch is very different from a relational database. The general recommendation with Elasticsearch is to denormalize your data: create single documents that capture all information of the entities that you want to query, even if you would store that information in separate tables in a relational database.

Scores are calculated at the shard level (the building block of an index). The multi search and the bool requests above will return the same scores for the documents.

In your case, the default scores coming out of the Companies and the Contacts indexes may be wildly different and not straightforward to intermingle. Scoring is a difficult subject actually. You may want to look at a different way to score your documents, for example switching to the boolean similarity.

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