당신은 붙여 넣은 것과 여러 가지 문제가 file
아니요 files
입니다. 당신이 매핑을 선택하면, 그 즉시 볼 것입니다 :
이
curl -XGET 'http://127.0.0.1:9200/files/_mapping?pretty=1'
# {
# "files" : {
# "files" : {
# "properties" : {
# "filename" : {
# "type" : "string",
# "analyzer" : "filename_analyzer"
# }
# }
# },
# "file" : {
# "properties" : {
# "filename" : {
# "type" : "string"
# }
# }
# }
# }
# }
2) 잘못된 분석기 당신은 lowercase
토크 나이를 지정하지만이 편지가 아닌 것은 제거
정의 (docs 참조), 귀하의 전화 번호는 완전히 삭제됩니다.
당신은 analyze API 이것을 확인할 수 있습니다
curl -XGET 'http://127.0.0.1:9200/_analyze?pretty=1&text=My_file_2012.01.13.doc&tokenizer=lowercase'
# {
# "tokens" : [
# {
# "end_offset" : 2,
# "position" : 1,
# "start_offset" : 0,
# "type" : "word",
# "token" : "my"
# },
# {
# "end_offset" : 7,
# "position" : 2,
# "start_offset" : 3,
# "type" : "word",
# "token" : "file"
# },
# {
# "end_offset" : 22,
# "position" : 3,
# "start_offset" : 19,
# "type" : "word",
# "token" : "doc"
# }
# ]
# }
3) Ngrams을
검색에 당신은 인덱스 분석 및 검색 분석기 모두에 N- 그램 토큰 필터를 포함한다. Ngram을 색인화하기를 원하기 때문에 색인 분석기에서는 문제가 없습니다. 그러나 검색 할 때 각 ngram이 아닌 전체 문자열을 검색하려고합니다. 예를 들어
, 당신은 4 길이 1의 ngrams와 인덱스 "abcd"
, 당신은이 토큰으로 종료됩니다 경우 :
a b c d ab bc cd abc bcd
그러나 당신은 또한 당신을 "dcba"
검색 (일치하지해야하는) 및 경우 ngrams와 검색어를 분석, 당신은 실제로에서 검색 :
d c b a dc cb ba dbc cba
그래서
a
,
b
,
c
및
d
이 일치합니다!
솔루션
먼저, 당신은 바로 분석기를 선택해야합니다. 사용자는 단어, 숫자 또는 날짜를 검색하지만 ile
은 file
과 일치하지 않을 것입니다. 대신, edge ngrams을 사용하면 Ngram을 각 단어의 시작 (또는 끝)에 고정시키는 것이 더 유용 할 것입니다.
또한 docx
등을 제외해야하는 이유는 무엇입니까? 확실히 사용자가 파일 형식을 검색하려고 할 것입니다.
그래서 문자 나 (사용 pattern tokenizer) 숫자가 아닌 것은 제거하여 작은 토큰으로 각 파일 이름을 깰 수 있습니다 :
My_first_file_2012.01.13.doc
=> my first file 2012 01 13 doc
그런 다음 인덱스 분석기, 우리는 또한 가장자리를 사용합니다 그 토큰의 각 ngrams 다음과 같이
my => m my
first => f fi fir firs first
file => f fi fil file
2012 => 2 20 201 201
01 => 0 01
13 => 1 13
doc => d do doc
우리는 인덱스를 만들 :
curl -XPUT 'http://127.0.0.1:9200/files/?pretty=1' -d '
{
"settings" : {
"analysis" : {
"analyzer" : {
"filename_search" : {
"tokenizer" : "filename",
"filter" : ["lowercase"]
},
"filename_index" : {
"tokenizer" : "filename",
"filter" : ["lowercase","edge_ngram"]
}
},
"tokenizer" : {
"filename" : {
"pattern" : "[^\\p{L}\\d]+",
"type" : "pattern"
}
},
"filter" : {
"edge_ngram" : {
"side" : "front",
"max_gram" : 20,
"min_gram" : 1,
"type" : "edgeNGram"
}
}
}
},
"mappings" : {
"file" : {
"properties" : {
"filename" : {
"type" : "string",
"search_analyzer" : "filename_search",
"index_analyzer" : "filename_index"
}
}
}
}
}
'
,
지금, 우리의 분석기가 제대로 작동하는지 테스트 :
filename_search :
curl -XGET 'http://127.0.0.1:9200/files/_analyze?pretty=1&text=My_first_file_2012.01.13.doc&analyzer=filename_search'
[results snipped]
"token" : "my"
"token" : "first"
"token" : "file"
"token" : "2012"
"token" : "01"
"token" : "13"
"token" : "doc"
filename_index :
curl -XGET 'http://127.0.0.1:9200/files/_analyze?pretty=1&text=My_first_file_2012.01.13.doc&analyzer=filename_index'
"token" : "m"
"token" : "my"
"token" : "f"
"token" : "fi"
"token" : "fir"
"token" : "firs"
"token" : "first"
"token" : "f"
"token" : "fi"
"token" : "fil"
"token" : "file"
"token" : "2"
"token" : "20"
"token" : "201"
"token" : "2012"
"token" : "0"
"token" : "01"
"token" : "1"
"token" : "13"
"token" : "d"
"token" : "do"
"token" : "doc"
확인을 - 올바르게 작동하는 것 같군.
curl -X POST "http://localhost:9200/files/file" -d '{ "filename" : "My_first_file_created_at_2012.01.13.doc" }'
curl -X POST "http://localhost:9200/files/file" -d '{ "filename" : "My_second_file_created_at_2012.01.13.pdf" }'
curl -X POST "http://localhost:9200/files/file" -d '{ "filename" : "Another file.txt" }'
curl -X POST "http://localhost:9200/files/file" -d '{ "filename" : "And_again_another_file.docx" }'
curl -X POST "http://localhost:9200/files/file" -d '{ "filename" : "foo.bar.txt" }'
curl -X POST "http://localhost:9200/files/_refresh"
을 그리고 검색하려고 : 그럼 몇 가지 문서를 추가 할 수
curl -XGET 'http://127.0.0.1:9200/files/file/_search?pretty=1' -d '
{
"query" : {
"text" : {
"filename" : "2012.01"
}
}
}
'
# {
# "hits" : {
# "hits" : [
# {
# "_source" : {
# "filename" : "My_second_file_created_at_2012.01.13.pdf"
# },
# "_score" : 0.06780553,
# "_index" : "files",
# "_id" : "PsDvfFCkT4yvJnlguxJrrQ",
# "_type" : "file"
# },
# {
# "_source" : {
# "filename" : "My_first_file_created_at_2012.01.13.doc"
# },
# "_score" : 0.06780553,
# "_index" : "files",
# "_id" : "ER5RmyhATg-Eu92XNGRu-w",
# "_type" : "file"
# }
# ],
# "max_score" : 0.06780553,
# "total" : 2
# },
# "timed_out" : false,
# "_shards" : {
# "failed" : 0,
# "successful" : 5,
# "total" : 5
# },
# "took" : 4
# }
성공!
#### UPDATE ####
나는 2012.01
에 대한 검색이 모두 2012.01.12
및 2012.12.01
그래서 내가 대신 text phrase 쿼리를 사용하는 쿼리를 변경 시도와 일치하는 것을 깨달았다. 그러나 이것은 효과가 없었습니다. 가장자리 ngram 필터는 각 ngram의 위치 수를 증가시킵니다 (각 ngram의 위치는 단어의 시작과 같을 것입니다).
위에서 언급 한 문제는 어떤 토큰과도 일치하려고 시도하는 query_string
, field
또는 text
쿼리를 사용할 때만 문제가됩니다. 그러나 text_phrase
쿼리의 경우 모든 토큰을 올바른 순서로 일치 시키려고 시도합니다.
다른 날짜로 다른 문서 문제, 인덱스를 설명하기 위해 :
curl -X POST "http://localhost:9200/files/file" -d '{ "filename" : "My_third_file_created_at_2012.12.01.doc" }'
curl -X POST "http://localhost:9200/files/_refresh"
그리고 상기와 동일한 검색을 수행 외설하는
curl -XGET 'http://127.0.0.1:9200/files/file/_search?pretty=1' -d '
{
"query" : {
"text" : {
"filename" : {
"query" : "2012.01"
}
}
}
}
'
# {
# "hits" : {
# "hits" : [
# {
# "_source" : {
# "filename" : "My_third_file_created_at_2012.12.01.doc"
# },
# "_score" : 0.22097087,
# "_index" : "files",
# "_id" : "xmC51lIhTnWplOHADWJzaQ",
# "_type" : "file"
# },
# {
# "_source" : {
# "filename" : "My_first_file_created_at_2012.01.13.doc"
# },
# "_score" : 0.13137488,
# "_index" : "files",
# "_id" : "ZUezxDgQTsuAaCTVL9IJgg",
# "_type" : "file"
# },
# {
# "_source" : {
# "filename" : "My_second_file_created_at_2012.01.13.pdf"
# },
# "_score" : 0.13137488,
# "_index" : "files",
# "_id" : "XwLNnSlwSeyYtA2y64WuVw",
# "_type" : "file"
# }
# ],
# "max_score" : 0.22097087,
# "total" : 3
# },
# "timed_out" : false,
# "_shards" : {
# "failed" : 0,
# "successful" : 5,
# "total" : 5
# },
# "took" : 5
# }
첫 번째 결과는 '날짜 2012.12.01
있다 가장 일치하는 2012.01
입니다. 그래서 해당 정확한 구문과 일치, 우리는 할 수 있습니다
curl -XGET 'http://127.0.0.1:9200/files/file/_search?pretty=1' -d '
{
"query" : {
"text_phrase" : {
"filename" : {
"query" : "2012.01",
"analyzer" : "filename_index"
}
}
}
}
'
# {
# "hits" : {
# "hits" : [
# {
# "_source" : {
# "filename" : "My_first_file_created_at_2012.01.13.doc"
# },
# "_score" : 0.55737644,
# "_index" : "files",
# "_id" : "ZUezxDgQTsuAaCTVL9IJgg",
# "_type" : "file"
# },
# {
# "_source" : {
# "filename" : "My_second_file_created_at_2012.01.13.pdf"
# },
# "_score" : 0.55737644,
# "_index" : "files",
# "_id" : "XwLNnSlwSeyYtA2y64WuVw",
# "_type" : "file"
# }
# ],
# "max_score" : 0.55737644,
# "total" : 2
# },
# "timed_out" : false,
# "_shards" : {
# "failed" : 0,
# "successful" : 5,
# "total" : 5
# },
# "took" : 7
# }
을 또는, 당신은 여전히 3 파일과 일치 할 경우 (사용자가 파일 이름에 단어의 일부를 기억할 수 있기 때문에,하지만 잘못된 순서로) , 당신은 두 쿼리를 실행하지만, 올바른 순서에있는 파일 이름의 중요성이 증가 할 수 있습니다
curl -XGET 'http://127.0.0.1:9200/files/file/_search?pretty=1' -d '
{
"query" : {
"bool" : {
"should" : [
{
"text_phrase" : {
"filename" : {
"boost" : 2,
"query" : "2012.01",
"analyzer" : "filename_index"
}
}
},
{
"text" : {
"filename" : "2012.01"
}
}
]
}
}
}
'
# [Fri Feb 24 16:31:02 2012] Response:
# {
# "hits" : {
# "hits" : [
# {
# "_source" : {
# "filename" : "My_first_file_created_at_2012.01.13.doc"
# },
# "_score" : 0.56892186,
# "_index" : "files",
# "_id" : "ZUezxDgQTsuAaCTVL9IJgg",
# "_type" : "file"
# },
# {
# "_source" : {
# "filename" : "My_second_file_created_at_2012.01.13.pdf"
# },
# "_score" : 0.56892186,
# "_index" : "files",
# "_id" : "XwLNnSlwSeyYtA2y64WuVw",
# "_type" : "file"
# },
# {
# "_source" : {
# "filename" : "My_third_file_created_at_2012.12.01.doc"
# },
# "_score" : 0.012931341,
# "_index" : "files",
# "_id" : "xmC51lIhTnWplOHADWJzaQ",
# "_type" : "file"
# }
# ],
# "max_score" : 0.56892186,
# "total" : 3
# },
# "timed_out" : false,
# "_shards" : {
# "failed" : 0,
# "successful" : 5,
# "total" : 5
# },
# "took" : 4
# }
와우, 이건 단지 해결책이 아닙니다. 그것은 제가 찾고 있었던 튜토리얼입니다 : D THX – Biggie
정말 고마워요. 정말 고마워요! – Robin
멋진 답변입니다. 그럼 SO20에 +20 버튼이 있습니까? – Ben