Q:

Building an effective Elasticsearch query for cross_fields with fuzziness

I know that Elasticsearch does not support fuzziness with the cross_fields type in a multi_match query. I have a very difficult time with the Elasticsearch API and so I'm finding it challenging to build an analogous query that searches across multiple document fields with fuzzy string matching.
I have an index called papers with various fields such as Title, Author.FirstName, Author.LastName, PublicationDate, Journal etc... I want to be able to query with a string like "John Doe paper title 2015 journal name". cross_fields is the perfect multi_match type but it doesn't support fuzziness which is critical for my application.
Can anyone suggest a reasonable way to approach this? I've spent hours going through solutions on SO and the Elasticsearch forums with little success.

A:

You can make use of copy_to field for this scenario. Basically you are copying all the values from different fields into one new field (my_search_field  in the below details) and on this field, you would be able to perform fuzzy query via fuzziness parameter using simple match query. 
Below is how a sample mapping, document and query would be:
Mapping:
PUT my_fuzzy_index
{
  "mappings": {
    "properties": {
      "my_search_field":{                    <---- Note this field
        "type": "text"
      },
      "Title":{
        "type": "text",
        "copy_to": "my_search_field"         <---- Note this 
      },
      "Author":{
        "type": "nested",
        "properties": {
          "FirstName":{
            "type":"text",
            "copy_to": "my_search_field"     <---- Note this 
          },
          "LastName":{
            "type":"text",
            "copy_to": "my_search_field"     <---- Note this 
          }
        }
      },
      "PublicationDate":{
        "type": "date",
        "copy_to": "my_search_field"        <---- Note this 
      },
      "Journal":{
        "type":"text",
        "copy_to": "my_search_field"        <---- Note this 
      }
    }
  }
}

Sample Document:
POST my_fuzzy_index/_doc/1
{
  "Title": "Fountainhead",
  "Author":[
    {
      "FirstName": "Ayn",
      "LastName": "Rand"
    }
  ],
  "PublicationDate": "2015",
  "Journal": "journal"
}

Query Request:
POST my_fuzzy_index/_search
{
  "query": {
    "match": {
      "my_search_field": {                                  <---- Note this field
        "query": "Aynnn Ranaad Fountainhead 2015 journal",
        "fuzziness": 3                                      <---- Fuzzy parameter
      }
    }
  }
}

Response:
{
  "took" : 15,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.1027813,
    "hits" : [
      {
        "_index" : "my_fuzzy_index",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.1027813,
        "_source" : {
          "Title" : "Fountainhead",
          "Author" : [
            {
              "FirstName" : "Ayn",
              "LastName" : "Rand"
            }
          ],
          "PublicationDate" : "2015",
          "Journal" : "journal"
        }
      }
    ]
  }
}

So instead of thinking of applying fuzzy query on multiple fields, you can instead go for this approach. That way your query would be simplified. 
Let me know if this helps!

