ES Query string query with separate unique value check











up vote
0
down vote

favorite












I have a query string query where search is made towards item names from an instant search input field



{
"query": {
"query_string" : {
"default_field" : "name",
"query" : "'.$searchQuery.'"
}
}
}


I would however like to include the search for item categories in the same query, hopefully tagged or separated somehow so they can be pushed to the top of the results in the front end. Item categories are in a separate field, _source for single items looks like this,



                "_source": {
"name": "Whatever Item Name",
"category": "Whatever Category",


So if the search input is "Whatever*" it should both be returning items with the name Whatever, but also separately return a list of unique category values which contain "Whatever" (not all items that have "Whatever Category"). So it should be returning items where names match, that can have any category, and also the available categories amongst all items separately. Is this possible to combine in one query?










share|improve this question


























    up vote
    0
    down vote

    favorite












    I have a query string query where search is made towards item names from an instant search input field



    {
    "query": {
    "query_string" : {
    "default_field" : "name",
    "query" : "'.$searchQuery.'"
    }
    }
    }


    I would however like to include the search for item categories in the same query, hopefully tagged or separated somehow so they can be pushed to the top of the results in the front end. Item categories are in a separate field, _source for single items looks like this,



                    "_source": {
    "name": "Whatever Item Name",
    "category": "Whatever Category",


    So if the search input is "Whatever*" it should both be returning items with the name Whatever, but also separately return a list of unique category values which contain "Whatever" (not all items that have "Whatever Category"). So it should be returning items where names match, that can have any category, and also the available categories amongst all items separately. Is this possible to combine in one query?










    share|improve this question
























      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      I have a query string query where search is made towards item names from an instant search input field



      {
      "query": {
      "query_string" : {
      "default_field" : "name",
      "query" : "'.$searchQuery.'"
      }
      }
      }


      I would however like to include the search for item categories in the same query, hopefully tagged or separated somehow so they can be pushed to the top of the results in the front end. Item categories are in a separate field, _source for single items looks like this,



                      "_source": {
      "name": "Whatever Item Name",
      "category": "Whatever Category",


      So if the search input is "Whatever*" it should both be returning items with the name Whatever, but also separately return a list of unique category values which contain "Whatever" (not all items that have "Whatever Category"). So it should be returning items where names match, that can have any category, and also the available categories amongst all items separately. Is this possible to combine in one query?










      share|improve this question













      I have a query string query where search is made towards item names from an instant search input field



      {
      "query": {
      "query_string" : {
      "default_field" : "name",
      "query" : "'.$searchQuery.'"
      }
      }
      }


      I would however like to include the search for item categories in the same query, hopefully tagged or separated somehow so they can be pushed to the top of the results in the front end. Item categories are in a separate field, _source for single items looks like this,



                      "_source": {
      "name": "Whatever Item Name",
      "category": "Whatever Category",


      So if the search input is "Whatever*" it should both be returning items with the name Whatever, but also separately return a list of unique category values which contain "Whatever" (not all items that have "Whatever Category"). So it should be returning items where names match, that can have any category, and also the available categories amongst all items separately. Is this possible to combine in one query?







      elasticsearch nested-queries






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 19 at 22:22









      Oscar

      93




      93
























          1 Answer
          1






          active

          oldest

          votes

















          up vote
          0
          down vote



          accepted










          You have a few options, but here are the two I would try first.



          Use a single query with tagged/named sub-queries. As you can see below, in a bool/should we are querying names and categories that match some_input with a slight boost on categories so they are ranked best and bubble up in the results. Also, the results are named either name_match or category_match so you know what kind of hits they are. You might want to play with the boost a little. Also you might need to adjust the size in order to return all the results you expect:



          {
          "size": 20,
          "query": {
          "bool": {
          "should": [
          {
          "query": {
          "query_string": {
          "default_field": "name",
          "query": "some_input",
          "_name": "name_match"
          }
          }
          },
          {
          "match": {
          "category": {
          "query": "some_input",
          "boost": 2,
          "_name": "category_match"
          }
          }
          }
          ]
          }
          }
          }


          The above query, however, might return the same category several times and some other category not at all, depending on the size you choose. So a better query would be the one below that leverages aggregations for the category part. It will return item matches in the hits section and unique category matches in the aggregation section:



          {
          "query": {
          "query_string": {
          "default_field": "name",
          "query": "some_input"
          }
          },
          "aggs": {
          "categories": {
          "filter": {
          "match": {
          "category": {
          "query": "some_input"
          }
          }
          },
          "aggs": {
          "categories": {
          "terms": {
          "field": "category",
          "size": 10
          }
          }
          }
          }
          }
          }


          UPDATE



          In order to compute the categories on all data, you can use post_filter instead of query:



          {
          "post_filter": {
          "query_string": {
          "default_field": "name",
          "query": "some_input"
          }
          },
          "aggs": {
          "categories": {
          "filter": {
          "match": {
          "category": {
          "query": "some_input"
          }
          }
          },
          "aggs": {
          "categories": {
          "terms": {
          "field": "category",
          "size": 10
          }
          }
          }
          }
          }
          }





          share|improve this answer























          • Thanks for the thorough explanation. Second query is exactly what I was looking for. Can however only get it to work for categories that are amongst the categories in the hits. Could it work for all indexed categories, regardless of if they are in the hits or not?
            – Oscar
            Nov 21 at 16:07










          • I've just updated my answer, please check.
            – Val
            Nov 26 at 14:19










          • Worked perfectly - thank you!
            – Oscar
            Nov 26 at 16:56










          • Awesome, glad it helepd!
            – Val
            Nov 26 at 16:57











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53383501%2fes-query-string-query-with-separate-unique-value-check%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          0
          down vote



          accepted










          You have a few options, but here are the two I would try first.



          Use a single query with tagged/named sub-queries. As you can see below, in a bool/should we are querying names and categories that match some_input with a slight boost on categories so they are ranked best and bubble up in the results. Also, the results are named either name_match or category_match so you know what kind of hits they are. You might want to play with the boost a little. Also you might need to adjust the size in order to return all the results you expect:



          {
          "size": 20,
          "query": {
          "bool": {
          "should": [
          {
          "query": {
          "query_string": {
          "default_field": "name",
          "query": "some_input",
          "_name": "name_match"
          }
          }
          },
          {
          "match": {
          "category": {
          "query": "some_input",
          "boost": 2,
          "_name": "category_match"
          }
          }
          }
          ]
          }
          }
          }


          The above query, however, might return the same category several times and some other category not at all, depending on the size you choose. So a better query would be the one below that leverages aggregations for the category part. It will return item matches in the hits section and unique category matches in the aggregation section:



          {
          "query": {
          "query_string": {
          "default_field": "name",
          "query": "some_input"
          }
          },
          "aggs": {
          "categories": {
          "filter": {
          "match": {
          "category": {
          "query": "some_input"
          }
          }
          },
          "aggs": {
          "categories": {
          "terms": {
          "field": "category",
          "size": 10
          }
          }
          }
          }
          }
          }


          UPDATE



          In order to compute the categories on all data, you can use post_filter instead of query:



          {
          "post_filter": {
          "query_string": {
          "default_field": "name",
          "query": "some_input"
          }
          },
          "aggs": {
          "categories": {
          "filter": {
          "match": {
          "category": {
          "query": "some_input"
          }
          }
          },
          "aggs": {
          "categories": {
          "terms": {
          "field": "category",
          "size": 10
          }
          }
          }
          }
          }
          }





          share|improve this answer























          • Thanks for the thorough explanation. Second query is exactly what I was looking for. Can however only get it to work for categories that are amongst the categories in the hits. Could it work for all indexed categories, regardless of if they are in the hits or not?
            – Oscar
            Nov 21 at 16:07










          • I've just updated my answer, please check.
            – Val
            Nov 26 at 14:19










          • Worked perfectly - thank you!
            – Oscar
            Nov 26 at 16:56










          • Awesome, glad it helepd!
            – Val
            Nov 26 at 16:57















          up vote
          0
          down vote



          accepted










          You have a few options, but here are the two I would try first.



          Use a single query with tagged/named sub-queries. As you can see below, in a bool/should we are querying names and categories that match some_input with a slight boost on categories so they are ranked best and bubble up in the results. Also, the results are named either name_match or category_match so you know what kind of hits they are. You might want to play with the boost a little. Also you might need to adjust the size in order to return all the results you expect:



          {
          "size": 20,
          "query": {
          "bool": {
          "should": [
          {
          "query": {
          "query_string": {
          "default_field": "name",
          "query": "some_input",
          "_name": "name_match"
          }
          }
          },
          {
          "match": {
          "category": {
          "query": "some_input",
          "boost": 2,
          "_name": "category_match"
          }
          }
          }
          ]
          }
          }
          }


          The above query, however, might return the same category several times and some other category not at all, depending on the size you choose. So a better query would be the one below that leverages aggregations for the category part. It will return item matches in the hits section and unique category matches in the aggregation section:



          {
          "query": {
          "query_string": {
          "default_field": "name",
          "query": "some_input"
          }
          },
          "aggs": {
          "categories": {
          "filter": {
          "match": {
          "category": {
          "query": "some_input"
          }
          }
          },
          "aggs": {
          "categories": {
          "terms": {
          "field": "category",
          "size": 10
          }
          }
          }
          }
          }
          }


          UPDATE



          In order to compute the categories on all data, you can use post_filter instead of query:



          {
          "post_filter": {
          "query_string": {
          "default_field": "name",
          "query": "some_input"
          }
          },
          "aggs": {
          "categories": {
          "filter": {
          "match": {
          "category": {
          "query": "some_input"
          }
          }
          },
          "aggs": {
          "categories": {
          "terms": {
          "field": "category",
          "size": 10
          }
          }
          }
          }
          }
          }





          share|improve this answer























          • Thanks for the thorough explanation. Second query is exactly what I was looking for. Can however only get it to work for categories that are amongst the categories in the hits. Could it work for all indexed categories, regardless of if they are in the hits or not?
            – Oscar
            Nov 21 at 16:07










          • I've just updated my answer, please check.
            – Val
            Nov 26 at 14:19










          • Worked perfectly - thank you!
            – Oscar
            Nov 26 at 16:56










          • Awesome, glad it helepd!
            – Val
            Nov 26 at 16:57













          up vote
          0
          down vote



          accepted







          up vote
          0
          down vote



          accepted






          You have a few options, but here are the two I would try first.



          Use a single query with tagged/named sub-queries. As you can see below, in a bool/should we are querying names and categories that match some_input with a slight boost on categories so they are ranked best and bubble up in the results. Also, the results are named either name_match or category_match so you know what kind of hits they are. You might want to play with the boost a little. Also you might need to adjust the size in order to return all the results you expect:



          {
          "size": 20,
          "query": {
          "bool": {
          "should": [
          {
          "query": {
          "query_string": {
          "default_field": "name",
          "query": "some_input",
          "_name": "name_match"
          }
          }
          },
          {
          "match": {
          "category": {
          "query": "some_input",
          "boost": 2,
          "_name": "category_match"
          }
          }
          }
          ]
          }
          }
          }


          The above query, however, might return the same category several times and some other category not at all, depending on the size you choose. So a better query would be the one below that leverages aggregations for the category part. It will return item matches in the hits section and unique category matches in the aggregation section:



          {
          "query": {
          "query_string": {
          "default_field": "name",
          "query": "some_input"
          }
          },
          "aggs": {
          "categories": {
          "filter": {
          "match": {
          "category": {
          "query": "some_input"
          }
          }
          },
          "aggs": {
          "categories": {
          "terms": {
          "field": "category",
          "size": 10
          }
          }
          }
          }
          }
          }


          UPDATE



          In order to compute the categories on all data, you can use post_filter instead of query:



          {
          "post_filter": {
          "query_string": {
          "default_field": "name",
          "query": "some_input"
          }
          },
          "aggs": {
          "categories": {
          "filter": {
          "match": {
          "category": {
          "query": "some_input"
          }
          }
          },
          "aggs": {
          "categories": {
          "terms": {
          "field": "category",
          "size": 10
          }
          }
          }
          }
          }
          }





          share|improve this answer














          You have a few options, but here are the two I would try first.



          Use a single query with tagged/named sub-queries. As you can see below, in a bool/should we are querying names and categories that match some_input with a slight boost on categories so they are ranked best and bubble up in the results. Also, the results are named either name_match or category_match so you know what kind of hits they are. You might want to play with the boost a little. Also you might need to adjust the size in order to return all the results you expect:



          {
          "size": 20,
          "query": {
          "bool": {
          "should": [
          {
          "query": {
          "query_string": {
          "default_field": "name",
          "query": "some_input",
          "_name": "name_match"
          }
          }
          },
          {
          "match": {
          "category": {
          "query": "some_input",
          "boost": 2,
          "_name": "category_match"
          }
          }
          }
          ]
          }
          }
          }


          The above query, however, might return the same category several times and some other category not at all, depending on the size you choose. So a better query would be the one below that leverages aggregations for the category part. It will return item matches in the hits section and unique category matches in the aggregation section:



          {
          "query": {
          "query_string": {
          "default_field": "name",
          "query": "some_input"
          }
          },
          "aggs": {
          "categories": {
          "filter": {
          "match": {
          "category": {
          "query": "some_input"
          }
          }
          },
          "aggs": {
          "categories": {
          "terms": {
          "field": "category",
          "size": 10
          }
          }
          }
          }
          }
          }


          UPDATE



          In order to compute the categories on all data, you can use post_filter instead of query:



          {
          "post_filter": {
          "query_string": {
          "default_field": "name",
          "query": "some_input"
          }
          },
          "aggs": {
          "categories": {
          "filter": {
          "match": {
          "category": {
          "query": "some_input"
          }
          }
          },
          "aggs": {
          "categories": {
          "terms": {
          "field": "category",
          "size": 10
          }
          }
          }
          }
          }
          }






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 26 at 14:19

























          answered Nov 20 at 4:38









          Val

          99.3k6127164




          99.3k6127164












          • Thanks for the thorough explanation. Second query is exactly what I was looking for. Can however only get it to work for categories that are amongst the categories in the hits. Could it work for all indexed categories, regardless of if they are in the hits or not?
            – Oscar
            Nov 21 at 16:07










          • I've just updated my answer, please check.
            – Val
            Nov 26 at 14:19










          • Worked perfectly - thank you!
            – Oscar
            Nov 26 at 16:56










          • Awesome, glad it helepd!
            – Val
            Nov 26 at 16:57


















          • Thanks for the thorough explanation. Second query is exactly what I was looking for. Can however only get it to work for categories that are amongst the categories in the hits. Could it work for all indexed categories, regardless of if they are in the hits or not?
            – Oscar
            Nov 21 at 16:07










          • I've just updated my answer, please check.
            – Val
            Nov 26 at 14:19










          • Worked perfectly - thank you!
            – Oscar
            Nov 26 at 16:56










          • Awesome, glad it helepd!
            – Val
            Nov 26 at 16:57
















          Thanks for the thorough explanation. Second query is exactly what I was looking for. Can however only get it to work for categories that are amongst the categories in the hits. Could it work for all indexed categories, regardless of if they are in the hits or not?
          – Oscar
          Nov 21 at 16:07




          Thanks for the thorough explanation. Second query is exactly what I was looking for. Can however only get it to work for categories that are amongst the categories in the hits. Could it work for all indexed categories, regardless of if they are in the hits or not?
          – Oscar
          Nov 21 at 16:07












          I've just updated my answer, please check.
          – Val
          Nov 26 at 14:19




          I've just updated my answer, please check.
          – Val
          Nov 26 at 14:19












          Worked perfectly - thank you!
          – Oscar
          Nov 26 at 16:56




          Worked perfectly - thank you!
          – Oscar
          Nov 26 at 16:56












          Awesome, glad it helepd!
          – Val
          Nov 26 at 16:57




          Awesome, glad it helepd!
          – Val
          Nov 26 at 16:57


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53383501%2fes-query-string-query-with-separate-unique-value-check%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          404 Error Contact Form 7 ajax form submitting

          How to know if a Active Directory user can login interactively

          TypeError: fit_transform() missing 1 required positional argument: 'X'