1

I'm trying to fetch a list of items that have the field: resellable: true.

Here is my data set I can see by visiting: my-domain.com/_all/listings/_search

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 4,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "collectibles",
        "_type" : "listing",
        "_id" : "SseZfNbpdpBxc3O",
        "_score" : 1.0,
        "_source" : {
          "data" : {
            "resellable" : true,
            "active" : true,
            "description" : "<p>1234 123 123 123</p>",
            "title" : "2134",
            "has_store" : true,
            "createdAt" : "Wed May 27 2020 04:23:18 GMT+0000 (Coordinated Universal Time)",
            "apiURL" : "kJ9zsIsdQG8TZrRfPco4",
            "id" : "SseZfNbpdpBxc3O",
            "state" : "PENDING",
            "amount" : "21",
          }
        }
      }
}

My query is using *NodeJS and ElasticSearch.js*

let results = await client.search({
    index: params.category,
    type: "listing",
    body: {
        query: {
            multi_match: {
                query: true,
                fields: ['resellable', 'active'],
                type: 'best_fields',
            }
        }
    }
})

The response is always no hits. I've tried a match, I've tried no best_fields and it doesn't seem to match the value.

What am I doing wrong here? Is there something else you need to do to query the _source.data level items?

ElasticSearch version: 7.4

Sowjanya R Bhat
  • 1,128
  • 10
  • 19
Zach
  • 468
  • 9
  • 17
  • 'resellable', 'active' should be 'data.resellable', data.'active'. If you will look at your output resellable and active and part of data field "_source" : { "data" : { "resellable" : true or you need to correct your document structure while indexing (remove data) – jaspreet chahal May 29 '20 at 08:27
  • @jaspreetchahal yes that did it. Thank you. Why is it only "data.active" instead of "_source.data.active"? – Zach May 29 '20 at 08:29
  • _source is an internal field in elastisearch which contains all the field, it is not added explicitly by us so no need to specify it – jaspreet chahal May 29 '20 at 08:31

1 Answers1

1

You are using the "true" in string format when using multi_match, while you indexed data in boolean format true and thats the reason you are not getting any hits.

I just noticed both of your multi_match fields(resellable and active) are boolean then why you are using the multi_match query, you should instead use the boolean filter query which is cached as well and gives better performance.

From the doc

Filter clauses are executed in filter context, meaning that scoring is ignored and clauses are considered for caching.

Sample index Mapping

{
    "mappings": {
        "properties": {
            "active": {
                "type": "boolean"
            },
            "resellable" :{
                "type" : "boolean"
            }
        }
    }
}

Index various example documents

{
   "active" : true,
   "resellable" : true
}

{
   "active" : true,
   "resellable" : false
}

{
   "active" : false,
   "resellable" : false
}

{
   "active" : false,
   "resellable" : true
}

Search query to get the doc where both values are true

{
    "query": {
        "bool": {
            "filter": [
                {
                    "match": {
                        "active": true
                    }
                },
                {
                    "match": {
                        "resellable": true
                    }
                }
            ]
        }
    }
}

Result

 "hits": [
         {
            "_index": "filterbool",
            "_type": "_doc",
            "_id": "1",
            "_score": 0.0,
            "_source": {
               "active": true,
               "resellable": true
            }
         }
      ]
  • I just tested without a string value and a boolean instead and it still returns zero hits. I've updated my post to reflect this. For the filter query - how do I set multiple fields for resellable and active? – Zach May 29 '20 at 08:21
  • @Zach thanks I am working on to provide a working sample. –  May 29 '20 at 08:22
  • @Zach, you want both `resellable` and `active` to be true correct as mentioned in your sample doc. –  May 29 '20 at 08:25
  • My query is dynamic, a user might have resellable, and no active, or active and no resellable. So I have an array with the filter options I pass into the "fields". But since I was returning 0 hits I hard coded the values to see if it was a problem with formatting or I was getting nothing regardless of formating. Filter query via terms seems like I might not be able to do dynamic terms? – Zach May 29 '20 at 08:26
  • @Zach, got it shouldn't be issue, I just got the solution and updating the answer(hint, you need to use the filter in your search query and refer the boolean filter query link in my answer) –  May 29 '20 at 08:28
  • @Zach did you solve it, I saw in question comments and overlooked the `data` field in your case but ideally you should use the filter clause to construct these queries as mentioned in the link and updated my answer with same `Filter clauses are executed in filter context, meaning that scoring is ignored and clauses are considered for caching.` –  May 29 '20 at 09:27
  • @Zach could you please check my last comments and reply :) Thanks in advance –  Jun 03 '20 at 02:19
  • Thanks for the replies. You helped a bunch and the issue is solved. it was an issue with data.resellable and not resellable, also with "true" and true typings – Zach Jun 23 '20 at 03:02
  • @Zach wow thanks a lot for following up and accepting the answer, it would help other readers and it would be great if you can upvote the answer if not done already, I just did on your question :) –  Jun 23 '20 at 05:27