1

I have the following document

    {
      "id": 1,
      "store": "xyz",
      "products": [
        {
          "object": {
            "name": "chair",
            "code": "2584"
          },
          "parts": [
            {
              "material": "wood"
            },
            {
              "material": "steel"
            }
          ]
        }
      ]
    },
    {
      "id": 2,
      "store": "abc",
      "products": [
        {
          "object": {
            "name": "chair",
            "code": "2584"
          },
          "parts": [
            {
              "material": "wood"
            },
            {
              "material": "steel"
            }
          ]
        },
        {
          "object": {
            "name": "table",
            "code": "2678"
          },
          "parts": [
            {
              "material": "wood"
            },
            {
              "material": "steel"
            }
          ]
        }
      ]
    }

So it goes like this : List of stores -> list of products -> list of parts

Now I would like to make a query to get all stores that have a chair in the products lists, but I don't want to have all the products in the response

For example the store "abc" should return for the query:

{
 "id": 2,
 "store": "abc",
 "products": [
   {
     "object": {
       "name": "chair",
       "code": "2584"
     },
     "parts": [
       {
         "material": "wood"
       },
       {
         "material": "steel"
       }
     ]
   }
}

Currently my mapping is :

"products.object": {
  "type": "object",
  "properties": {
    "code": {
      "type": "text",
      "fielddata": true
    },
    "name": {
      "type": "text",
      "fielddata": true
    }
  }
},
"products.parts": {
  "store": false,
  "type": "long",
  "index": false
},

What type of query should I use and how the mapping should be made ?

Thank you in advance

EDIT :

To add to my question, my goal is to remove all products that dont match the query inside the hits array

So the response should contain the id, the variable "store", and so on. But not the products that dont match the name "chair" (to echo my example)

SnoWhite
  • 109
  • 1
  • 2
  • 8

1 Answers1

0

You can use query with Terms Aggregation:

{
  "size": 0,
  "query": {
    "bool": {
      "must": {
        "products.object.name": "chair"
      }
    }
  },
  "aggs": {
    "stores_aggregation": {
      "terms": {
        "field": "store"
      }
    }
  }
}

--> size:0 determine not to return any documents.

--> query will filter only by chair

--> aggregation will give you list of buckets containing all relevant stores, look here for further information.

Another thing, I would suggest you to go nested with Nested Datatype, see my answer here to understand the benefits.

Eli
  • 4,576
  • 1
  • 27
  • 39
  • Hi, i've tried your solution and it works, but it seems my question was not precise enough, i'm updating my question with more info – SnoWhite Nov 08 '17 at 13:30
  • To add more to my previous comment : Your solution means that I can't only get the field "store" inside the aggregation. But I would like to keep all the info of my document, except for the products that I didnt searched i.e : removing the product from the array inside the hits – SnoWhite Nov 08 '17 at 13:53
  • It's indeed possible with **nested type**. I'll try to add some example. My answer [here](https://stackoverflow.com/questions/46900249/searching-for-nested-documents-on-a-specific-parent/46932687#46932687) can also help you understand the concept. – Eli Nov 09 '17 at 08:18