How do I add a weight (or prefilter) for a phrase

2020-07-27 06:29发布

I am new to phrase suggester and have been reading the docs. The completion suggester has a way to add a weight so that the results are scored. The phrase suggester has no such option unless I am missing. I have:

POST test/_search
{
  "suggest": {
    "text": "noble prize",
    "simple_phrase": {
      "phrase": {
        "field": "title.trigram",
        "size": 1,
        "gram_size": 3,
        "direct_generator": [ {
          "field": "title.trigram",
          "suggest_mode": "always"
        } ],
        "highlight": {
          "pre_tag": "<em>",
          "post_tag": "</em>"
        }
      }
    }
  }
}

I would like to make some of the suggestions more/less important and/or exclude some. Image the above comes back with "nobel prize" but I want to exclude that suggestion or manually weight it as less important. Is that possible?

The example comes directly from the first example found here

EDIT Since all phrases passed in by my users are saved in elasticsearch the above code will not suggest a better phrase. For instance if "noble prize" and "nobel prize" are both in the index and user types "noble prize" I want to suggest "nobel prize" but it won't. Most user types in nobel prize correctly so I can increment each time a query is used and therefore suggest the correct one. Make sense good.

Another Edit: it's weird that they assume your index won't grow and that you don't want to prioritize phrases like the completion suggester allows you to do.

A complete example:

PUT test
{
  "settings": {
    "index": {
      "number_of_shards": 1,
      "analysis": {
        "analyzer": {
          "trigram": {
            "type": "custom",
            "tokenizer": "standard",
            "filter": ["standard", "shingle"]
          },
          "reverse": {
            "type": "custom",
            "tokenizer": "standard",
            "filter": ["standard", "reverse"]
          }
        },
        "filter": {
          "shingle": {
            "type": "shingle",
            "min_shingle_size": 2,
            "max_shingle_size": 3
          }
        }
      }
    }
  },
  "mappings": {
    "test": {
      "properties": {
        "title": {
          "type": "text",
          "fields": {
            "trigram": {
              "type": "text",
              "analyzer": "trigram"
            },
            "reverse": {
              "type": "text",
              "analyzer": "reverse"
            }
          }
        }
      }
    }
  }
}
POST test/test
{"title": "noble prize", "weight": 1}
POST test/test
{"title": "nobel prize", "weight": 2}

Query:

GET /test/_search
{
   "suggest": {
      "text": "noble prize",
      "simple_phrase": {
         "phrase": {
            "field": "title.trigram",
            "size": 1,
            "gram_size": 3,
            "direct_generator": [
               {
                  "field": "title.trigram",
                  "suggest_mode": "always"
               }
            ],
             "collate": {
               "query": {
                  "inline": {
                     "match": {
                        "title": "{{suggestion}}"
                     }
                  }
               },
               "prune": true
            },
            "highlight": {
               "pre_tag": "<em>",
               "post_tag": "</em>"
            }
         }
      }
   }
}

Results in (wrongly) "noble prize":

{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "failed": 0
  },
  "hits": {
    "total": 0,
    "max_score": 0,
    "hits": []
  },
  "suggest": {
    "simple_phrase": [
      {
        "text": "noble prize",
        "offset": 0,
        "length": 11,
        "options": []
      }
    ]
  }
}

1条回答
走好不送
2楼-- · 2020-07-27 06:56

Which functionality you want to implement? Did You Mean or Autocomplete? In the case I can give other suggestions to you.

To Prune your suggestion result you can use collate like this:

{
   "suggest": {
      "text": "iphon",
      "simple_phrase": {
         "phrase": {
            "field": "title.trigram",
            "size": 1,
            "gram_size": 3,
            "direct_generator": [
               {
                  "field": "title.trigram",
                  "suggest_mode": "always"
               }
            ],
             "collate": {
               "query": {
                  "inline": {
                     "match": {
                        "title": "{{suggestion}}"
                     }
                  }
               },
               "prune": true
            },
            "highlight": {
               "pre_tag": "<em>",
               "post_tag": "</em>"
            }
         }
      }
   }
}

In the result you will have a "collate_match": true/false which indicates if any suggestion is matched your collate query.

查看更多
登录 后发表回答