Elasticsearch - поисковые символы (содержатся в строках) и оценки tf-idf - PullRequest
2 голосов
/ 21 июня 2020

как сделать подстановочный знак поиска и оценки tf-idf. Например, когда я ищу так,

GET /test_es/_search?explain=true // return idf / dt scores
{
  "explain":true,
  "query": {
    "query_string": {
      "query": "bar^5",
      "fields"  : ["field"]
    }
  }
}

он возвращает idf и td score, но когда я ищу, как с подстановочными знаками (содержит).

GET /test_es/_search?explain=true  // NOT RETURN idf/td score
{
   "explain":true,
  "query": {
    "query_string": {
      "query": "b*",
      "fields"  : ["field"]
    }
  }
}

как я могу выполнить поиск с подстановочные знаки (использование содержит в строке) и включают оценки IDF-TD?

например, у меня есть 3 документа: « foo », « foo bar », « foo baz », когда я ищу его вот так

GET /foo2/_search?explain=true
{
   "explain":true,
  "query": {
    "query_string": {
      "query": "fo *",
      "fields"  : ["field"]
    }
  }
}

Результат Elasticsearch

    "hits" : [
  {
    "_shard" : "[foo2][0]",
    "_node" : "z8bjI0T1T8Oq6Z2OwFyIKw",
    "_index" : "foo2",
    "_type" : "_doc",
    "_id" : "3",
    "_score" : 1.0,
    "_source" : {
      "field" : "foo bar"
    },
    "_explanation" : {
      "value" : 1.0,
      "description" : "sum of:",
      "details" : [
        {
          "value" : 1.0,
          "description" : "*:*",
          "details" : [ ]
        }
      ]
    }
  },
  {
    "_shard" : "[foo2][0]",
    "_node" : "z8bjI0T1T8Oq6Z2OwFyIKw",
    "_index" : "foo2",
    "_type" : "_doc",
    "_id" : "2",
    "_score" : 1.0,
    "_source" : {
      "field" : "foo"
    },
    "_explanation" : {
      "value" : 1.0,
      "description" : "sum of:",
      "details" : [
        {
          "value" : 1.0,
          "description" : "*:*",
          "details" : [ ]
        }
      ]
    }
  },
  {
    "_shard" : "[foo2][0]",
    "_node" : "z8bjI0T1T8Oq6Z2OwFyIKw",
    "_index" : "foo2",
    "_type" : "_doc",
    "_id" : "1",
    "_score" : 1.0,
    "_source" : {
      "field" : "foo baz"
    },
    "_explanation" : {
      "value" : 1.0,
      "description" : "sum of:",
      "details" : [
        {
          "value" : 1.0,
          "description" : "*:*",
          "details" : [ ]
        }
      ]
    }
  }
]

Но я ожидаю, что «foo» должно быть первый результат с наивысшим баллом, потому что он соответствует% 100, я ошибаюсь?

Ответы [ 2 ]

0 голосов
/ 22 июня 2020

Обновленный ответ на основе комментариев в моем первом ответе

Запросы с подстановочными знаками в основном относятся к запросам на уровне терминов и по умолчанию использует constant_score_boolean

Изменяя значение параметра rewrite , вы можете повлиять на производительность и релевантность поиска. У него есть различные варианты оценки, вы можете выбрать любой из них в соответствии с вашими требованиями.

Но в соответствии с вашим вариантом использования вы также можете использовать фильтр edge_ngram. Граничные N-граммы полезны для запросов типа "поиск по мере ввода". Чтобы узнать больше об этом и используемом ниже сопоставлении, обратитесь к этой официальной документации

Сопоставление индексов:

{
  "settings": {
    "analysis": {
      "analyzer": {
        "autocomplete": {
          "tokenizer": "autocomplete",
          "filter": [
            "lowercase"
          ]
        },
        "autocomplete_search": {
          "tokenizer": "lowercase"
        }
      },
      "tokenizer": {
        "autocomplete": {
          "type": "edge_ngram",
          "min_gram": 2,
          "max_gram": 10,
          "token_chars": [
            "letter"
          ]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "autocomplete",
        "search_analyzer": "autocomplete_search"
      }
    }
  }
}

Пример индекса данные:

{ "title":"foo" }
{ "title":"foo bar" }
{ "title":"foo baz" }

Поисковый запрос:

{
  "query": {
    "match": {
      "title": {
        "query": "fo"
      }
    }
  }
}

Результат поиска:

"hits": [
            {
                "_index": "foo6",
                "_type": "_doc",
                "_id": "1",
                "_score": 0.15965709,        --> Maximum score
                "_source": {
                    "title": "foo"
                }
            },
            {
                "_index": "foo6",
                "_type": "_doc",
                "_id": "2",
                "_score": 0.12343237,
                "_source": {
                    "title": "foo bar"
                }
            },
            {
                "_index": "foo6",
                "_type": "_doc",
                "_id": "3",
                "_score": 0.12343237,
                "_source": {
                    "title": "foo baz"
                }
            }
        ]

Чтобы узнать больше об основах использования Ngrams в Elasticsearch, вы можете обратиться к здесь

0 голосов
/ 21 июня 2020

Поскольку вы ничего не упомянули о взятых вами данных, я проиндексировал следующие данные:

Данные образца индекса:

{
    "message": "A fox is a wild animal."
}
{
    "message": "That fox must have killed the hen."
}
{
    "message": "the quick brown fox jumps over the lazy dog"
}

Поисковый запрос:

GET/{{index-name}}/_search 

{
  "query": {
    "query_string": {
      "fields": [
        "message"                       ---> You can add more fields here
      ],
      "query": "quick^2 fox*"
    }
  }
}

Вышеупомянутый запрос ищет все документы, содержащие fox, но здесь, поскольку boost применяется к quick, поэтому документ, содержащий quick fox будет иметь более высокий балл по сравнению с другими документами.

Этот запрос вернет оценку tf-IDF. Оператор повышения используется, чтобы сделать один термин более актуальным, чем другой.

Чтобы узнать больше об этом, обратитесь к этой официальной документации по Повышение в dsl-query-string

Чтобы узнать больше об алгоритме tf-IDF, вы можете обратиться к этому блогу

Если вы хотите выполнить поиск по нескольким полям, вы можете повысить баллы в определенное поле

См. this и this , чтобы узнать больше.

Обновление 1:

Данные индекса:

{
  "title": "foo bar"
}
{
  "title": "foo baz"
}
{
  "title": "foo"
}

Поисковый запрос:

{
  "query": {
    "query_string": {
      "query": "foo *"         --> You can just add a space between 
                                   foo and *
     }
  }
}

Результат поиска:

"hits": [
         {
            "_index": "foo2",
            "_type": "_doc",
            "_id": "1",
            "_score": 1.9808292,       --> foo matches exactly, so the 
                                           score is maximum
            "_source": {
               "title": "foo"
            }
         },
         {
            "_index": "foo2",
            "_type": "_doc",
            "_id": "2",
            "_score": 1.1234324,
            "_source": {
               "title": "foo bar"
            }
         },
         {
            "_index": "foo2",
            "_type": "_doc",
            "_id": "3",
            "_score": 1.1234324,
            "_source": {
               "title": "foo baz"
            }
         }
      ]
...