0
votes

I'm trying to acheve this goals:

  1. Filter out results by bool query, like "status=1"
  2. Filter out results by bool range query, like "discance: gte 10 AND lte 60"
  3. Filter out results by match at least one int value from int array
  4. Search words in many fields with calculating document score. Some fields needs wildcard, some boosting, like importantfield^2, somefield*, someotherfield^0.75
  5. All above points join by AND operator. All terms in one point join by OR operator.

Now I wrote something like this, but wildcards not working. Searching "abc" don't finds "abcd" in "name" field. How to solve this?

{
  "filtered": {
    "query": {
      "multi_match": {
        "query": "John Doe",
        "fields": [
          "*name*^1.75",
          "someObject.name",
          "tagsArray",
          "*description*",
          "ownerName"
        ]
      }
    },
    "filter": {
      "bool": {
        "must": [
          {
            "term": {
              "status": 2
            }
          },
          {
            "bool": {
              "should": [
                {
                  "term": {
                    "someIntsArray": 1
                  }
                },
                {
                  "term": {
                    "someIntsArray": 5
                  }
                }
              ]
            }
          },
          {
            "range": {
              "distanceA": {
                "lte": 100
              }
            }
          },
          {
            "range": {
              "distanceB": {
                "gte": 50,
                "lte": 100
              }
            }
          }
        ]
      }
    }
  }
}

Mappings:

{
  "documentId": {
    "type": "integer"
  },
  "ownerName": {
    "type": "string",
    "index": "not_analyzed"
  },
  "description": {
    "type": "string"
  },
  "status": {
    "type": "byte"
  },
  "distanceA": {
    "type": "short"
  },
  "createdAt": {
    "type": "date",
    "format": "yyyy-MM-dd HH:mm:ss"
  },
  "distanceB": {
    "type": "short"
  },
  "someObject": {
    "properties": {
      "someObject_id": {
        "type": "integer"
      },
      "name": {
        "type": "string",
        "index": "not_analyzed"
      }
    }
  },
  "someIntsArray": {
    "type": "integer"
  },
  "tags": {
    "type": "string",
    "index": "not_analyzed"
  }
}
1
Please join your mappings.LeBigCat
Sorry, I forgot abut that.TomaszKane

1 Answers

1
votes

You can make use of Query String if you would want to apply wildcard for multiple fields and at the same time apply various boosting values for individual fields:

Below is how your query would be:

POST <your_index_name>/_search
{  
   "query":{  
      "bool":{  
         "must":[  
            {  
               "query_string":{  
                  "query":"abc*",
                  "fields":[  
                     "*name*^1.75",
                     "someObject.name",
                     "tagsArray",
                     "*description*",
                     "ownerName"
                  ]
               }
            }
         ],
         "filter":{  
            "bool":{  
               "must":[  
                  {  
                     "term":{  
                        "status":"2"
                     }
                  },
                  {  
                     "bool":{  
                        "minimum_should_match":1,
                        "should":[  
                           {  
                              "term":{  
                                 "someIntsArray":1
                              }
                           },
                           {  
                              "term":{  
                                 "someIntsArray":5
                              }
                           }
                        ]
                     }
                  },
                  {  
                     "range":{  
                        "distanceA":{  
                           "lte":100
                        }
                     }
                  },
                  {  
                     "range":{  
                        "distanceB":{  
                           "gte": 50,
                           "lte":100
                        }
                     }
                  }
               ]
            }
         }
      }
   }
}

Note that for the field someIntsArray, I've made use of "minimum_should_match":1 so that you won't end up with documents that'd have neither of those values.

Updated Answer:

Going by the updated comment, you can have the fields with wildcard search used by query_string and you can make use of simple match query with boosting as shown in below. Include both these queries (can even add more match queries depending on your requirement) in a combine should clause. That way you can control where wildcard query can be used and where not.

{  
   "query":{  
      "bool":{  
         "should":[  
            {  
               "query_string":{  
                  "query":"joh*",
                  "fields":[  
                     "name^2"
                  ]
               }
            },
            {  
               "match":{  
                  "description":{  
                     "query":"john",
                     "boost":15
                  }
               }
            }
         ],
         "filter":{  
            "bool":{  
               "must":[  
                  {  
                     "term":{  
                        "status":"2"
                     }
                  },
                  {  
                     "bool":{  
                        "minimum_should_match":1,
                        "should":[  
                           {  
                              "term":{  
                                 "someIntsArray":1
                              }
                           },
                           {  
                              "term":{  
                                 "someIntsArray":5
                              }
                           }
                        ]
                     }
                  },
                  {  
                     "range":{  
                        "distanceA":{  
                           "lte":100
                        }
                     }
                  },
                  {  
                     "range":{  
                        "distanceB":{  
                           "lte":100
                        }
                     }
                  }
               ]
            }
         }
      }
   }
}

Let me know if this helps