ElasticSearch: выделение с помощью Stemming - PullRequest
0 голосов
/ 20 апреля 2019

Я прочитал этот вопрос и попытался понять документацию здесь , но это сложно.

Проблема (я думаю):

[обновление 1]

Я использую Scala для своего кода и интерфейса с ES High Level Java API.

У меня настроен анализатор стволов. Если я ищу responsibilities, я получаю результаты для responsibilities и responsibility. Это здорово.

НО

Только документы с термином responsibilities возвращают основные моменты. Это связано с тем, что поиск выполняется по основному содержанию, т. Е. responsib. Тем не менее, основное внимание уделяется незаполненному контенту. Следовательно, он находит responsibilities, который был критерием поиска, но не responsibility, который не был.

Если я установлю подсветку для выделения содержимого на стебле, он вообще ничего не возвращает. Я думаю, потому что он сравнивает resonsib с responsibilities

Поиск

Я использую API высокого уровня Java. Проблема не в самом коде. В настоящее время я выделяю только поле content, возвращая только responsibilities. Подсветка content.english, кажется, ничего не возвращает

 private def buildHighlighter(): HighlightBuilder = {
    import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder
    val highlightBuilder = new HighlightBuilder
    val highlightContent = new HighlightBuilder.Field("content")
    highlightContent.highlighterType("unified")
    highlightBuilder.field(highlightContent)
    highlightBuilder

  }

Отображение (в сумме)

{
	"settings": {
		"number_of_shards": 3,
		"analysis": {
			"filter": {
				"english_stop": {
					"type": "stop",
					"stopwords": "_english_"
				},
				"english_keywords": {
					"type": "keyword_marker",
					"keywords": []
				},
				"english_stemmer": {
					"type": "stemmer",
					"language": "english"
				},
				"english_possessive_stemmer": {
					"type": "stemmer",
					"language": "possessive_english"
				}
			},
			"analyzer": {
				"english": {
					"tokenizer": "standard",
					"filter": [
						"english_possessive_stemmer",
						"lowercase",
						"english_stop",
						"english_keywords",
						"english_stemmer"
					]
				}
			}
		}
	},
	"mappings": {
		"_doc": {
			"properties": {
				"title": {
					"type": "text",
          "fields": {
           "english": {
             "type":     "text",
              "analyzer": "english"
            }
          }
				},
				"content": {
          "type": "text",
           "fields": {
            "english": {
              "type":     "text",
               "analyzer": "english"
             }
          }
			
			}
		}
	}
}

[обновление 2]

Scala-код для поиска:

def searchByField(indices: Seq[ESIndexName], terms: Seq[(String, String)], size: Int = 20): SearchResponse = {

    val searchRequest = new SearchRequest
    searchRequest.indices(indices.map(idx => idx.completeIndexName()): _*)
    searchRequest.source(buildTargetFieldsMatchQuery(terms, size))

    searchRequest.indicesOptions(IndicesOptions.strictSingleIndexNoExpandForbidClosed())

    client.search(searchRequest, RequestOptions.DEFAULT)
  }

и запрос строится следующим образом:

private def buildTargetFieldsMatchQuery(termsByField: Seq[(String, String)], size: Int): SearchSourceBuilder = {

    val query = new BoolQueryBuilder

    termsByField.foreach {
      case (field, term) =>

        if (field == "content") {
          logger.debug(field + " should have " + term)
          query.should(new MatchQueryBuilder(field+standardAnalyzer, term.toLowerCase))
          query.should(new MatchQueryBuilder(field, term.toLowerCase))
        }
        else if (field == "title"){
          logger.debug(field + " should have " + term)
          query.should(new MatchQueryBuilder(field+standardAnalyzer, term.toLowerCase())).boost
        }
        else {
          logger.debug(field + " should have " + term)
        query.should(new MatchQueryBuilder(field, term.toLowerCase))
      }

    }
    val sourceBuilder: SearchSourceBuilder = new SearchSourceBuilder()
    sourceBuilder.query(query)
    sourceBuilder.from(0)
    sourceBuilder.size(size)
    sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS))
    sourceBuilder.highlighter(buildHighlighter())

  }

1 Ответ

0 голосов
/ 20 апреля 2019

С простым REST у меня работает нормально:

PUT test
{
  "settings": {
    "number_of_shards": 1,
    "analysis": {
      "filter": {
        "english_stop": {
          "type": "stop",
          "stopwords": "_english_"
        },
        "english_keywords": {
          "type": "keyword_marker",
          "keywords": []
        },
        "english_stemmer": {
          "type": "stemmer",
          "language": "english"
        },
        "english_possessive_stemmer": {
          "type": "stemmer",
          "language": "possessive_english"
        }
      },
      "analyzer": {
        "english": {
          "tokenizer": "standard",
          "filter": [
            "english_possessive_stemmer",
            "lowercase",
            "english_stop",
            "english_keywords",
            "english_stemmer"
          ]
        }
      }
    }
  },
  "mappings": {
    "_doc": {
      "properties": {
        "content": {
          "type": "text",
          "fields": {
            "english": {
              "type": "text",
              "analyzer": "english"
            }
          }
        }
      }
    }
  }
}

POST test/_doc/
{
  "content": "This is my responsibility"
}

POST test/_doc/
{
  "content": "These are my responsibilities"
}

GET test/_search
{
  "query": {
    "match": {
      "content.english": "responsibilities"
    }
  },
  "highlight": {
    "fields": {
      "content.english": {
        "type": "unified"
      }
    }
  }
}

В результате получается:

"hits" : [
  {
    "_index" : "test",
    "_type" : "_doc",
    "_id" : "5D5PPGoBqgTTLzdtM-_Y",
    "_score" : 0.18232156,
    "_source" : {
      "content" : "This is my responsibility"
    },
    "highlight" : {
      "content.english" : [
        "This is my <em>responsibility</em>"
      ]
    }
  },
  {
    "_index" : "test",
    "_type" : "_doc",
    "_id" : "5T5PPGoBqgTTLzdtZe8U",
    "_score" : 0.18232156,
    "_source" : {
      "content" : "These are my responsibilities"
    },
    "highlight" : {
      "content.english" : [
        "These are my <em>responsibilities</em>"
      ]
    }
  }
]

Глядя на ваш Java / Groovy (?) Код, он выглядит достаточно близко к примеру в документации . Не могли бы вы записать фактический запрос, который вы выполняете, чтобы мы могли выяснить, что идет не так? Обычно это должно работать следующим образом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...