토큰 화/색인 생성 용어 (Lucene에서) 또는 해당 검색에 대한 검색 엔진을 처리하는 가장 좋은 방법은 무엇인지 궁금합니다.검색 인덱스 - 12 = 12
"12"= "열둘"
"MX1"= "MX 하나"
는 모든 I 내장 기능이 간과 한 있나요?
토큰 화/색인 생성 용어 (Lucene에서) 또는 해당 검색에 대한 검색 엔진을 처리하는 가장 좋은 방법은 무엇인지 궁금합니다.검색 인덱스 - 12 = 12
"12"= "열둘"
"MX1"= "MX 하나"
는 모든 I 내장 기능이 간과 한 있나요?
Lucene에서 가장 간단한 방법은 초기 문자열이 토큰 화 된 후 사용할 두 개의 별도 토큰 필터를 만드는 것입니다. 첫 번째 것은 숫자와 비 숫자의 순서를 나눌 필요가 있습니다. 그런 다음 두 번째 숫자 (숫자 문자열)를 숫자 (철자) 숫자로 변환합니다.
여기 PyLucene (제외 오프셋 및 위치 속성 논리)과 예입니다 :
class AlphaNumberBoundaryFilter(lucene.PythonTokenFilter):
seq = re.compile(r"((?:\d+")|(?:\D+))")
def __init__(self, in_stream):
lucene.PythonTokenFilter.__init__(self, in_stream)
term = self.term = self.addAttribute(lucene.TermAttribute.class_)
# Get tokens.
tokens = []
while in_stream.incrementToken():
tokens.append(term.term())
# Filter tokens.
self.tokens = self.filter(tokens)
# Setup iterator.
self.iter = iter(self.tokens)
def filter(self, tokens):
seq = self.seq
return [split for token in tokens for split in seq.findall(token)]
def incrementToken(self):
try:
self.term.setTermBuffer(next(self.iter))
except StopIteration:
return False
return True
class NumberToWordFilter(lucene.PythonTokenFilter):
num_map = {0: "zero", 1: "one", 2: "two", 3: "three", 4: "four", 5: "five", 6: "six", 7: "seven", 8: "eight", 9: "nine", 10: "ten", 11: "eleven", 12: "twelve", 13: "thirteen", 14: "fourteen", 15: "fifteen", 16: "sixteen", 17: "seventeen", 18: "eighteen", 19: "nineteen", 20: "twenty", 30: "thirty", 40: "forty", 50: "fifty", 60: "sixty", 70: "seventy", 80: "eighty", 90: "ninety", 100: "hundred", 1000: "thousand", 1000000: "million"}
is_num = re.compile(r"^\d+$")
def __init__(self, in_stream):
lucene.PythonTokenFilter.__init__(self, in_stream)
term = self.term = self.addAttribute(lucene.TermAttribute.class_)
# Get tokens.
tokens = []
while in_stream.incrementToken():
tokens.append(term.term())
# Filter tokens.
self.tokens = self.filter(tokens)
# Setup iterator.
self.iter = iter(self.tokens)
def filter(self, tokens):
num_map = self.num_map
is_num = self.is_num
final = []
for token in tokens:
if not is_num.match(token):
final.append(token)
continue
# Reverse digits from token.
digits = token.lstrip('0')[::-1]
if not digits:
# We have a zero.
final.append(num_map[0])
continue
# Group every 3 digits and iterate over digit groups in reverse
# so that groups are yielded in the original order and in each
# group: 0 -> ones, 1 -> tens, 2 -> hundreds
groups = [digits[i:i+3] for i in xrange(0, len(digits), 3)][::-1]
scale = len(groups) - 1
result = []
for oth in groups:
l = len(oth)
if l == 3 and oth[2] != '0':
# 2 -> x
# 1 -> .
# 0 -> .
result.append(num_map[int(oth[2])])
result.append(num_map[100])
if l >= 2:
if oth[1] == '1':
# 1 -> 1
# 0 -> x
result.append(num_map[int(oth[1::-1])])
else:
if oth[1] != '0':
# 1 -> x (x >= 2)
# 0 -> x
result.append(num_map[int(oth[1]) * 10])
if oth[0] != '0':
result.append(num_map[int(oth[0])])
elif oth[0] != '0':
# 0 -> x
result.append(num_map[int(oth[0])])
# Add scale modifier.
s = scale
if s % 2:
result.append(num_map[1000])
while s >= 2:
result.append(num_map[1000000])
s -= 2
scale -= 1
final.extend(result)
return final
def incrementToken(self):
try:
self.term.setTermBuffer(next(self.iter))
except StopIteration:
return False
return True
Lucene을 보았습니까 SynonymFilter?
당신이 사전에 가능한 모든 매핑을 수용 할 필요 SynonymMap와 SynonymFilter를 사용하지 않을까요? –
예. 그러나 동의어로 작업 할 때 IDF로 인해 사전에 작업하는 것이 좋습니다. http://stackoverflow.com/questions/7272368/change-dynamically-elasticsearch-synonyms/7273651#7273651을 참조하십시오. – jpountz