user3350303
user3350303

Reputation: 51

One way synonym search in Elasticsearch

I want to implement synonym one way search in Elasticsearch. One way search meaning if I define a => x,y,z and search for 'a', search result should include all the documents containing words x,y,z,a which is working now. But if I search for 'x' then search result should contain document which contains only 'x' and not 'a'.

Is this possible in Elasticsearch ?

Upvotes: 4

Views: 1946

Answers (3)

davisca
davisca

Reputation: 1184

I would implement it with synonyms using generic expansion aka genre expansion and different analyzers for index-time and query-time

Synonyms at index time:

Bob => Bob, Robert
Rob => Rob, Robert

The format is like

word => the same word, more generic word, even more generic, etc

Query time: no synonyms applied

Query for "Bob" will return only documents where "Bob" was.

Query for "Rob" will return only documents where "Rob" was.

Query for "Robert" will return documents where "Bob", "Rob" and "Robert" was.

Upvotes: 0

andrew.fox
andrew.fox

Reputation: 7933

I've implemented one-way synonyms by inverting the synonym expression:

e.g.:

Robert => Bob, Rob
Bob => Robert

but I had to use this analyzer with synonyms is different way. In mapping, synonyms are hooked to a new field:

"FirstName": {
  "type": "string",
  "analyzer": "standard",
  "search_analyzer": "standard",
  "fields": {
    "raw": {
      "type": "string",
      "analyzer": "standard"
    },
    "synonym": {
      "type": "string",
      "analyzer": "firstname_synonym_analyzer"
    }
  }
},

And search looks like this:

 "bool": {
    "should": [
       {
          "match": {
             "FirstName": {
                "query": "Jo"
             }
          }
       },
       {
          "match": {
             "FirstName.synonym": {
                "query": "Jo"
             }
          }
       }
    ],
    "minimum_should_match": 1
 }

This way first field contains normal value, second just possible synonyms. So looking for Bob finds Robert, but not Rob.

Upvotes: 0

Andreas Neumann
Andreas Neumann

Reputation: 10894

You can not do this in a synonym relation as the behaviour you are explaining is a hyperonym/hyponym relation.

You can achieve such a behaviour on index-time though.

So for each occurrence of a you also index x,y,z. Using an additional field for this would be a good idea to not mess up the scores.

This behaviour is sadly not part of elasticsearch and has to be implemented by hand while feeding the data.

Upvotes: 4

Related Questions