0
votes

I have an index (name: "index1") pointing to multiple documents in ElasticSearch.

The format(json) of a document is -

{
  "_index": "index1",
  "_type": "someType",
  "_id": "randomIDBlahBlah",
  "_source": {
    "version": "2018",
    "fields": [
      {
        "field": "A.B",
        "lineNumber": 1
      },
      {
        "field": "C.D",
        "lineNumber": 2
      },
      {
        "field": "A.E",
        "lineNumber": 3
      }]
  },
  "fields": {
    "created": [
      "2017-01-19T20:11:07.977Z"
    ]
  },
  "sort": [
    2324343
  ]
}

Here is the mapping -

{
  "index1": {
    "mappings": {
      "mapping": {
        "properties": {
          "branch": {
            "type": "text"
          },
          "created": {
            "type": "date"
          },
          "fields": {
            "type": "nested",
            "properties": {
              "field": {
                "type": "text"
              },
              "lineNumber": {
                "type": "integer"
              }
            }
          }
        }
      }
    }
  }
}

Similarly, there are multiple documents under that index, same format, but different field data.

Now, I am trying to perform the below mentioned Elastic Search on a specific field (here - A.B), it is giving me all the results from all the documents as if it's a search for all the fields.

I want to see only that specific field result, not all the results.

This is my ES query -

POST index1/_search
{
 "query": {
   "bool": {
     "must": [
       {
         "bool": {
           "should": [
             {
               "nested": {
                 "path": "fields",
                 "query": {
                   "match_phrase": {
                     "fields.field": "A.B"
                   }
                 }
               }
             }
           ]
         }
       }
     ]
   }
 }
}

Where am I doing wrong in the ES query?

2
What is the datatype of fields.field? Or I would be more understandable if you can add the mapping of index1 to your question. - Nishant
fields.field is of type String. I've added the mapping of index1 in the question. - user9755712

2 Answers

0
votes

If your field is not type keyword, then you must add the type .keyword

this is generated automatically by ES on "type": "text" fields

GET index1/_search
{
 "query": {
   "bool": {
     "must": [
       {
         "bool": {
           "should": [
             {
               "nested": {
                 "path": "fields",
                 "query": {
                   "match_phrase": {
                     "fields.field.keyword: "A.B"
                   }
                 }
               }
             }
           ]
         }
       }
     ]
   }
 }
}```
0
votes

The query you have used will give you desired result. This can be better written as below if you don't require scoring:

{
  "query": {
    "bool": {
      "filter": [
        {
          "nested": {
            "path": "fields",
            "query": {
              "match": {
                "fields.field": "A.B"
              }
            },
            "inner_hits": {
               "size": 10
            }           
          }
        }
      ]
    }
  },
  "_source": {
     "excludes": [
        "fields"
     ]
  }
}

Inner hits is what you are looking for. When there is a match elastic returns the complete nested object. If you want only the matching nested objects then you have to use inner_hits.

UPDATE: If no fields are required other than the inner hits then you can set "_source":false. You can also use include and exclude to filter source as per your requirement