title: Elasticsearch match exact terms with spaces across different fields
body: <p>My data in elastic is setup with different fields: categories, subcategories, instruments and moods. My goal is to provide results with only exact matches for all of the keywords passed to it and only return results that match everything. So far, this seems to work until I use a keyword that consists of multiple words separated with a space, like so:</p>
  
  <pre><code>"query": {
      "bool": {
        "must": [
          {
            "match": {
              "categories": "Electronic"
            }
          },
          {
            "match": {
              "categories": "Pop"
            }
          },
          {
            "match": {
              "instruments": "Female Vocal"
            }
          }
        ]
      }
  }
  </code></pre>
  
  <p>My data in ES consists of this type of data:</p>
  
  <pre><code>[name] =&gt; Some Data Name
  [categories] =&gt; Electronic,Pop
  [subcategories] =&gt; 1970s,Alternative,Experimental,Retro
  [instruments] =&gt; Electronic Drums,Male Vocal,Synth
  [moods] =&gt; Fun,Futuristic,Pulsing,Quirky,Rhythmic
  </code></pre>
  
  <p>So, it's matching the "Vocal" part of the instruments field, but doesn't perform an exact match for "Female Vocal". </p>
  
  <p>Would this be solved by an ES filter perhaps? </p>
  
  <p><strong>EDIT</strong>:
  To account for other characters, I expanded the sample data set a bit:</p>
  
  <pre><code>[categories]=&gt;R&amp;B,Dance/House
  [instruments] =&gt; Electronic Drums,Male Vocal,Synth
  [moods] =&gt; Fun,Futuristic,Pulsing,Quirky,Rhythmic
  </code></pre>
  
  <p>So, there might be ampersands, slashes and spaces used. A comma would separate separate terms. </p>
  
  <p><strong>SOLVED</strong>
  I ended up looking more into analyzers and realized that I probably need to create a custom one to account for the boundaries of my keywords. </p>
  
  <pre><code>myesurl/tracks/_settings    
  {
        "index": {
          "analysis": {
            "tokenizer": {
              "comma": {
                "type": "pattern",
                "pattern": ","
              }
            },
            "analyzer": {
              "tracks_analyzer": {
                "type": "custom",
                "tokenizer": "comma",
                "filter": [
                  "trim",
                  "lowercase"
                ]
              }
            }
          }
        }
      }
  </code></pre>
  
  <p>Then I setup a mapping:</p>
  
  <pre><code>{
    "track": {
      "properties": {
        "categories": {
          "type": "string",
          "analyzer": "tracks_analyzer"
        },
        "subcategories": {
          "type": "string",
          "analyzer": "tracks_analyzer"
        },
        "instruments": {
          "type": "string",
          "analyzer": "tracks_analyzer"
        },
        "moods": {
          "type": "string",
          "analyzer": "tracks_analyzer"
        }
      }
    }
  }
  </code></pre>
  
  <p>And then pushed the content into the elasticsearch. Seemed to work as intended. It now accounts for any character in the keyword, as long as the keyword matches to a token that was created by separated commas. </p>