パス階層トークナイザー
path_hierarchy
トークナイザーは、ファイルシステムパスのような階層的な値を受け取り、パスセパレーターで分割し、ツリー内の各コンポーネントに対して用語を出力します。path_hierarcy
トークナイザーは、内部で Lucene の PathHierarchyTokenizer を使用します。
例の出力
Python
resp = client.indices.analyze(
tokenizer="path_hierarchy",
text="/one/two/three",
)
print(resp)
Ruby
response = client.indices.analyze(
body: {
tokenizer: 'path_hierarchy',
text: '/one/two/three'
}
)
puts response
Js
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
トークナイザーは、次のパラメーターを受け入れます:
delimiter |
パスセパレーターとして使用する文字。デフォルトは / です。 |
replacement |
区切り文字として使用するオプションの置換文字。 デフォルトは delimiter です。 |
buffer_size |
単一のパスで用語バッファに読み込まれる文字数。 デフォルトは 1024 です。用語バッファは、すべてのテキストが消費されるまでこのサイズで成長します。この設定を変更しないことをお勧めします。 |
reverse |
true の場合、Lucene のReversePathHierarchyTokenizer を使用します。 これはドメインのような階層に適しています。デフォルトは false です。 |
skip |
スキップする初期トークンの数。デフォルトは 0 です。 |
例の設定
この例では、path_hierarchy
トークナイザーを -
文字で分割し、/
で置き換えるように設定します。最初の2つのトークンはスキップされます:
Python
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)
Ruby
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
Js
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
トークナイザーを使用してパスを分析することで、ファイルパス文字列の異なる部分で結果をフィルタリングできます。
この例では、インデックスに2つのカスタムアナライザーを設定し、それらのアナライザーをファイル名を格納する file_path
テキストフィールドのマルチフィールドに適用します。2つのアナライザーのうちの1つは逆トークン化を使用します。その後、サンプルドキュメントがインデックスされ、2人の異なるユーザーの写真フォルダー内のいくつかのファイルパスを表します。
Python
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)
Ruby
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
Js
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
も標準アナライザーによって作成された用語の1つであるため、関連性が高く評価されます。
Python
resp = client.search(
index="file-path-test",
query={
"match": {
"file_path": "/User/bob/photos/2017/05"
}
},
)
print(resp)
Ruby
response = client.search(
index: 'file-path-test',
body: {
query: {
match: {
file_path: '/User/bob/photos/2017/05'
}
}
}
)
puts response
Js
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
フィールドを使用します。
Python
resp = client.search(
index="file-path-test",
query={
"term": {
"file_path.tree": "/User/alice/photos/2017/05/16"
}
},
)
print(resp)
Ruby
response = client.search(
index: 'file-path-test',
body: {
query: {
term: {
'file_path.tree' => '/User/alice/photos/2017/05/16'
}
}
}
)
puts response
Js
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"
}
}
}
このトークナイザーの逆パラメーターを使用すると、ファイルパスの反対側から一致させることも可能です。たとえば、個々のファイル名や深いレベルのサブディレクトリなどです。次の例は、マッピングで逆パラメーターを使用するように設定された file_path.tree_reversed
フィールド内の任意のディレクトリで my_photo1.jpg
という名前のすべてのファイルを検索する方法を示しています。
Python
resp = client.search(
index="file-path-test",
query={
"term": {
"file_path.tree_reversed": {
"value": "my_photo1.jpg"
}
}
},
)
print(resp)
Ruby
response = client.search(
index: 'file-path-test',
body: {
query: {
term: {
'file_path.tree_reversed' => {
value: 'my_photo1.jpg'
}
}
}
}
)
puts response
Js
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"
}
}
}
}
前方および逆の両方で生成されたトークンを表示することは、同じファイルパス値に対して作成されたトークンを示すのに役立ちます。
Python
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)
Ruby
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
Js
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
を持つファイルパスを探し、アリスの写真ディレクトリ内に存在する必要があります。
Python
resp = client.search(
index="file-path-test",
query={
"bool": {
"must": {
"match": {
"file_path": "16"
}
},
"filter": {
"term": {
"file_path.tree": "/User/alice"
}
}
}
},
)
print(resp)
Ruby
response = client.search(
index: 'file-path-test',
body: {
query: {
bool: {
must: {
match: {
file_path: '16'
}
},
filter: {
term: {
'file_path.tree' => '/User/alice'
}
}
}
}
}
)
puts response
Js
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" }
}
}
}
}