Токенизатор иерархии путей
Токенизатор path_hierarchy принимает значение иерархического типа, например, путь к файлу, разделяет его по разделителю путей и генерирует токен для каждого компонента в дереве. Токенизатор path_hierarcy использует подкласс PathHierarchyTokenizer из Lucene.
Пример вывода
resp = client.indices.analyze(
tokenizer="path_hierarchy",
text="/one/two/three",
)
print(resp) response = client.indices.analyze(
body: {
tokenizer: 'path_hierarchy',
text: '/one/two/three'
}
)
puts response const response = await client.indices.analyze({
tokenizer: "path_hierarchy",
text: "/one/two/three",
});
console.log(response); POST _analyze
{
"tokenizer": "path_hierarchy",
"text": "/one/two/three"
} Вышеупомянутый текст породит следующие токены:
[ /one, /one/two, /one/two/three ]
Настройка
Токенизатор path_hierarchy принимает следующие параметры:
| | Символ, используемый в качестве разделителя путей. По умолчанию |
| | Необязательный символ для замены разделителя. По умолчанию |
| | Количество символов, читаемых в буфер токена за один проход. По умолчанию |
| | Если |
| | Количество начальных токенов для пропуска. По умолчанию |
Пример конфигурации
В данном примере мы настраиваем токенизатор path_hierarchy для разделения по символам - и для их замены на /. Первые два токена пропускаются:
resp = client.indices.create(
index="my-index-000001",
settings={
"analysis": {
"analyzer": {
"my_analyzer": {
"tokenizer": "my_tokenizer"
}
},
"tokenizer": {
"my_tokenizer": {
"type": "path_hierarchy",
"delimiter": "-",
"replacement": "/",
"skip": 2
}
}
}
},
)
print(resp)
resp1 = client.indices.analyze(
index="my-index-000001",
analyzer="my_analyzer",
text="one-two-three-four-five",
)
print(resp1) response = client.indices.create(
index: 'my-index-000001',
body: {
settings: {
analysis: {
analyzer: {
my_analyzer: {
tokenizer: 'my_tokenizer'
}
},
tokenizer: {
my_tokenizer: {
type: 'path_hierarchy',
delimiter: '-',
replacement: '/',
skip: 2
}
}
}
}
}
)
puts response
response = client.indices.analyze(
index: 'my-index-000001',
body: {
analyzer: 'my_analyzer',
text: 'one-two-three-four-five'
}
)
puts response const response = await client.indices.create({
index: "my-index-000001",
settings: {
analysis: {
analyzer: {
my_analyzer: {
tokenizer: "my_tokenizer",
},
},
tokenizer: {
my_tokenizer: {
type: "path_hierarchy",
delimiter: "-",
replacement: "/",
skip: 2,
},
},
},
},
});
console.log(response);
const response1 = await client.indices.analyze({
index: "my-index-000001",
analyzer: "my_analyzer",
text: "one-two-three-four-five",
});
console.log(response1); PUT my-index-000001
{
"settings": {
"analysis": {
"analyzer": {
"my_analyzer": {
"tokenizer": "my_tokenizer"
}
},
"tokenizer": {
"my_tokenizer": {
"type": "path_hierarchy",
"delimiter": "-",
"replacement": "/",
"skip": 2
}
}
}
}
}
POST my-index-000001/_analyze
{
"analyzer": "my_analyzer",
"text": "one-two-three-four-five"
} Вышеприведенный пример генерирует следующие токены:
[ /three, /three/four, /three/four/five ]
Если мы установим reverse в значение true, то получим следующее:
[ one/two/three/, two/three/, three/ ]
Подробные примеры
Общим случаем применения токенизатора path_hierarchy является фильтрация результатов по путям к файлам. При индексировании пути к файлу вместе с данными, использование токенизатора path_hierarchy для анализа пути позволяет фильтровать результаты по различным частям строки пути к файлу.
В этом примере настраивается индекс с двумя пользовательскими анализаторами, которые применяются к многопольным полям текстового поля file_path, хранящему имена файлов. Один из двух анализаторов использует обратную токенизацию. Затем индексируются некоторые примерные документы, представляющие пути к файлам фотографий в папках фотографий двух разных пользователей.
resp = client.indices.create(
index="file-path-test",
settings={
"analysis": {
"analyzer": {
"custom_path_tree": {
"tokenizer": "custom_hierarchy"
},
"custom_path_tree_reversed": {
"tokenizer": "custom_hierarchy_reversed"
}
},
"tokenizer": {
"custom_hierarchy": {
"type": "path_hierarchy",
"delimiter": "/"
},
"custom_hierarchy_reversed": {
"type": "path_hierarchy",
"delimiter": "/",
"reverse": "true"
}
}
}
},
mappings={
"properties": {
"file_path": {
"type": "text",
"fields": {
"tree": {
"type": "text",
"analyzer": "custom_path_tree"
},
"tree_reversed": {
"type": "text",
"analyzer": "custom_path_tree_reversed"
}
}
}
}
},
)
print(resp)
resp1 = client.index(
index="file-path-test",
id="1",
document={
"file_path": "/User/alice/photos/2017/05/16/my_photo1.jpg"
},
)
print(resp1)
resp2 = client.index(
index="file-path-test",
id="2",
document={
"file_path": "/User/alice/photos/2017/05/16/my_photo2.jpg"
},
)
print(resp2)
resp3 = client.index(
index="file-path-test",
id="3",
document={
"file_path": "/User/alice/photos/2017/05/16/my_photo3.jpg"
},
)
print(resp3)
resp4 = client.index(
index="file-path-test",
id="4",
document={
"file_path": "/User/alice/photos/2017/05/15/my_photo1.jpg"
},
)
print(resp4)
resp5 = client.index(
index="file-path-test",
id="5",
document={
"file_path": "/User/bob/photos/2017/05/16/my_photo1.jpg"
},
)
print(resp5) response = client.indices.create(
index: 'file-path-test',
body: {
settings: {
analysis: {
analyzer: {
custom_path_tree: {
tokenizer: 'custom_hierarchy'
},
custom_path_tree_reversed: {
tokenizer: 'custom_hierarchy_reversed'
}
},
tokenizer: {
custom_hierarchy: {
type: 'path_hierarchy',
delimiter: '/'
},
custom_hierarchy_reversed: {
type: 'path_hierarchy',
delimiter: '/',
reverse: 'true'
}
}
}
},
mappings: {
properties: {
file_path: {
type: 'text',
fields: {
tree: {
type: 'text',
analyzer: 'custom_path_tree'
},
tree_reversed: {
type: 'text',
analyzer: 'custom_path_tree_reversed'
}
}
}
}
}
}
)
puts response
response = client.index(
index: 'file-path-test',
id: 1,
body: {
file_path: '/User/alice/photos/2017/05/16/my_photo1.jpg'
}
)
puts response
response = client.index(
index: 'file-path-test',
id: 2,
body: {
file_path: '/User/alice/photos/2017/05/16/my_photo2.jpg'
}
)
puts response
response = client.index(
index: 'file-path-test',
id: 3,
body: {
file_path: '/User/alice/photos/2017/05/16/my_photo3.jpg'
}
)
puts response
response = client.index(
index: 'file-path-test',
id: 4,
body: {
file_path: '/User/alice/photos/2017/05/15/my_photo1.jpg'
}
)
puts response
response = client.index(
index: 'file-path-test',
id: 5,
body: {
file_path: '/User/bob/photos/2017/05/16/my_photo1.jpg'
}
)
puts response const response = await client.indices.create({
index: "file-path-test",
settings: {
analysis: {
analyzer: {
custom_path_tree: {
tokenizer: "custom_hierarchy",
},
custom_path_tree_reversed: {
tokenizer: "custom_hierarchy_reversed",
},
},
tokenizer: {
custom_hierarchy: {
type: "path_hierarchy",
delimiter: "/",
},
custom_hierarchy_reversed: {
type: "path_hierarchy",
delimiter: "/",
reverse: "true",
},
},
},
},
mappings: {
properties: {
file_path: {
type: "text",
fields: {
tree: {
type: "text",
analyzer: "custom_path_tree",
},
tree_reversed: {
type: "text",
analyzer: "custom_path_tree_reversed",
},
},
},
},
},
});
console.log(response);
const response1 = await client.index({
index: "file-path-test",
id: 1,
document: {
file_path: "/User/alice/photos/2017/05/16/my_photo1.jpg",
},
});
console.log(response1);
const response2 = await client.index({
index: "file-path-test",
id: 2,
document: {
file_path: "/User/alice/photos/2017/05/16/my_photo2.jpg",
},
});
console.log(response2);
const response3 = await client.index({
index: "file-path-test",
id: 3,
document: {
file_path: "/User/alice/photos/2017/05/16/my_photo3.jpg",
},
});
console.log(response3);
const response4 = await client.index({
index: "file-path-test",
id: 4,
document: {
file_path: "/User/alice/photos/2017/05/15/my_photo1.jpg",
},
});
console.log(response4);
const response5 = await client.index({
index: "file-path-test",
id: 5,
document: {
file_path: "/User/bob/photos/2017/05/16/my_photo1.jpg",
},
});
console.log(response5); PUT file-path-test
{
"settings": {
"analysis": {
"analyzer": {
"custom_path_tree": {
"tokenizer": "custom_hierarchy"
},
"custom_path_tree_reversed": {
"tokenizer": "custom_hierarchy_reversed"
}
},
"tokenizer": {
"custom_hierarchy": {
"type": "path_hierarchy",
"delimiter": "/"
},
"custom_hierarchy_reversed": {
"type": "path_hierarchy",
"delimiter": "/",
"reverse": "true"
}
}
}
},
"mappings": {
"properties": {
"file_path": {
"type": "text",
"fields": {
"tree": {
"type": "text",
"analyzer": "custom_path_tree"
},
"tree_reversed": {
"type": "text",
"analyzer": "custom_path_tree_reversed"
}
}
}
}
}
}
POST file-path-test/_doc/1
{
"file_path": "/User/alice/photos/2017/05/16/my_photo1.jpg"
}
POST file-path-test/_doc/2
{
"file_path": "/User/alice/photos/2017/05/16/my_photo2.jpg"
}
POST file-path-test/_doc/3
{
"file_path": "/User/alice/photos/2017/05/16/my_photo3.jpg"
}
POST file-path-test/_doc/4
{
"file_path": "/User/alice/photos/2017/05/15/my_photo1.jpg"
}
POST file-path-test/_doc/5
{
"file_path": "/User/bob/photos/2017/05/16/my_photo1.jpg"
} Поиск по конкретной строке пути к файлу в текстовом поле находит все примерные документы, причем документы Боба имеют наивысший рейтинг, так как bob также является одним из токенов, созданных стандартным анализатором, повышающим релевантность документов Боба.
resp = client.search(
index="file-path-test",
query={
"match": {
"file_path": "/User/bob/photos/2017/05"
}
},
)
print(resp) response = client.search(
index: 'file-path-test',
body: {
query: {
match: {
file_path: '/User/bob/photos/2017/05'
}
}
}
)
puts response const response = await client.search({
index: "file-path-test",
query: {
match: {
file_path: "/User/bob/photos/2017/05",
},
},
});
console.log(response); GET file-path-test/_search
{
"query": {
"match": {
"file_path": "/User/bob/photos/2017/05"
}
}
} Просто найти или отфильтровать документы с путями к файлам, которые существуют в конкретной директории, используя поле file_path.tree.
resp = client.search(
index="file-path-test",
query={
"term": {
"file_path.tree": "/User/alice/photos/2017/05/16"
}
},
)
print(resp) response = client.search(
index: 'file-path-test',
body: {
query: {
term: {
'file_path.tree' => '/User/alice/photos/2017/05/16'
}
}
}
)
puts response const response = await client.search({
index: "file-path-test",
query: {
term: {
"file_path.tree": "/User/alice/photos/2017/05/16",
},
},
});
console.log(response); GET file-path-test/_search
{
"query": {
"term": {
"file_path.tree": "/User/alice/photos/2017/05/16"
}
}
} Используя параметр обратного порядка для этого токенизатора, также можно выполнять поиск с другого конца пути к файлу, например, отдельных имён файлов или глубоко вложенных подкаталогов. Следующий пример демонстрирует поиск всех файлов с именем my_photo1.jpg в любой директории через поле file_path.tree_reversed, настроенное с параметром обратного порядка в отображении.
resp = client.search(
index="file-path-test",
query={
"term": {
"file_path.tree_reversed": {
"value": "my_photo1.jpg"
}
}
},
)
print(resp) response = client.search(
index: 'file-path-test',
body: {
query: {
term: {
'file_path.tree_reversed' => {
value: 'my_photo1.jpg'
}
}
}
}
)
puts response const response = await client.search({
index: "file-path-test",
query: {
term: {
"file_path.tree_reversed": {
value: "my_photo1.jpg",
},
},
},
});
console.log(response); GET file-path-test/_search
{
"query": {
"term": {
"file_path.tree_reversed": {
"value": "my_photo1.jpg"
}
}
}
} Просмотр токенов, сгенерированных как в прямом, так и в обратном порядке, полезен для демонстрации токенов, созданных для одного и того же значения пути к файлу.
resp = client.indices.analyze(
index="file-path-test",
analyzer="custom_path_tree",
text="/User/alice/photos/2017/05/16/my_photo1.jpg",
)
print(resp)
resp1 = client.indices.analyze(
index="file-path-test",
analyzer="custom_path_tree_reversed",
text="/User/alice/photos/2017/05/16/my_photo1.jpg",
)
print(resp1) response = client.indices.analyze(
index: 'file-path-test',
body: {
analyzer: 'custom_path_tree',
text: '/User/alice/photos/2017/05/16/my_photo1.jpg'
}
)
puts response
response = client.indices.analyze(
index: 'file-path-test',
body: {
analyzer: 'custom_path_tree_reversed',
text: '/User/alice/photos/2017/05/16/my_photo1.jpg'
}
)
puts response const response = await client.indices.analyze({
index: "file-path-test",
analyzer: "custom_path_tree",
text: "/User/alice/photos/2017/05/16/my_photo1.jpg",
});
console.log(response);
const response1 = await client.indices.analyze({
index: "file-path-test",
analyzer: "custom_path_tree_reversed",
text: "/User/alice/photos/2017/05/16/my_photo1.jpg",
});
console.log(response1); POST file-path-test/_analyze
{
"analyzer": "custom_path_tree",
"text": "/User/alice/photos/2017/05/16/my_photo1.jpg"
}
POST file-path-test/_analyze
{
"analyzer": "custom_path_tree_reversed",
"text": "/User/alice/photos/2017/05/16/my_photo1.jpg"
} Также полезно использовать фильтрацию по путям к файлам в сочетании с другими типами поисков, как в этом примере, где ищутся все пути к файлам с 16, которые также должны находиться в фотокаталоге Алисы.
resp = client.search(
index="file-path-test",
query={
"bool": {
"must": {
"match": {
"file_path": "16"
}
},
"filter": {
"term": {
"file_path.tree": "/User/alice"
}
}
}
},
)
print(resp) response = client.search(
index: 'file-path-test',
body: {
query: {
bool: {
must: {
match: {
file_path: '16'
}
},
filter: {
term: {
'file_path.tree' => '/User/alice'
}
}
}
}
}
)
puts response const response = await client.search({
index: "file-path-test",
query: {
bool: {
must: {
match: {
file_path: "16",
},
},
filter: {
term: {
"file_path.tree": "/User/alice",
},
},
},
},
});
console.log(response); GET file-path-test/_search
{
"query": {
"bool" : {
"must" : {
"match" : { "file_path" : "16" }
},
"filter": {
"term" : { "file_path.tree" : "/User/alice" }
}
}
}
}
© 2023-2025 Elasticsearch
As of September 2024, Elasticsearch is available under a choice of three licenses: the Server Side Public License (SSPL), the Elastic License, or the AGPLv3 (OSI approved).
Elasticsearch and the Elasticsearch logo are trademarks of Elasticsearch B.V., registered in the U.S. and in other countries.
https://www.elastic.co/guide/en/elasticsearch/reference/8.17/analysis-pathhierarchy-tokenizer.html