gpt4 book ai didi

Java Lucene 4.5 如何不区分大小写搜索

转载 作者:搜寻专家 更新时间:2023-10-31 08:16:46 26 4
gpt4 key购买 nike

我们已经实现了 Java Lucene 搜索引擎 4.5,我正在尝试搜索内容,即使字段值不区分大小写(例如,如果我搜索名称为“Banglore”的城市,我会得到一个结果,但是当我搜索一个名为“banglore”的城市我得到 0 个结果)。

我已经使用 StandardAnalyzer 来分析数据,并使用 WildcardQuery 来匹配 Like 条件(我尝试了提到的 here 但没有成功) .

我不确定我哪里做错了。感谢任何有关解决此区分大小写问题的指导。

public SearchHelper
{
Analyzer analyzer;

Directory index;
public IndexSearcher searcher = null;
public IndexWriter indexWriter = null;
public QueryParser parser = null;
private static int hitsPerPage = 100;

/**
* @param indexFileLocation
* @throws IOException
*/
public SearchHelper(String indexFileLocation) throws IOException
{
// this.analyzer =new StandardAnalyzer();
this.analyzer = new CaseStandardAnalyzer();
// analyzer = new ThaiAnalyzer();
this.index = FSDirectory.open(java.nio.file.Paths.get(indexFileLocation));
}

/**
* @param create
* @return
* @throws IOException
*/
public IndexWriter getIndexWriter(boolean create) throws IOException
{
if (indexWriter == null)
{
IndexWriterConfig iwc = new IndexWriterConfig(this.analyzer);
this.indexWriter = new IndexWriter(this.index, iwc);
}
return this.indexWriter;
} //End of getIndexWriter

/**
* @throws IOException
*/
public void closeIndexWriter() throws IOException
{
if (this.indexWriter != null)
{
this.indexWriter.commit();//optimize(); LUCENE_36
this.indexWriter.close();
}
} //End closeIndexWriter

/**
* @param indexFileLocation
* @throws CorruptIndexException
* @throws IOException
*/
public void startSearch(String indexFileLocation) throws CorruptIndexException, IOException
{
// searcher = new IndexSearcher(FSDirectory.open(new File(indexFileLocation)));

IndexReader reader = DirectoryReader.open(FSDirectory.open(java.nio.file.Paths.get(indexFileLocation)));
// IndexReader.open(this.index);
// open(getIndexWriter(true), true);
this.searcher = new IndexSearcher(reader);
}

/**
* @param fieldNames
* @param fieldValues
* @return
* @throws IOException
* @throws ParseException
*
* <p></p>
* https://stackoverflow.com/questions/2005084/how-to-specify-two-fields-in-lucene-queryparser
*/
public ScoreDoc[] searchSEO(String[] fieldNames, String[] fieldValues, int limitSize) throws IOException, ParseException
{
this.analyzer = new StandardAnalyzer();
int searchFieldSize = (null == fieldNames) ? 0 : fieldNames.length;

BooleanQuery booleanQuery = new BooleanQuery();

for (int i = 0; i < searchFieldSize; i++)
{
Query query1 = searchIndexWithWildcardQuery(fieldNames[i], fieldValues[i]);
addQueries(booleanQuery, query1, 2);
}

TopScoreDocCollector collector = null; // Or use by default hitsPerPage instead limitSize

if (limitSize > 0)
{
collector = TopScoreDocCollector.create(limitSize);
} else {
collector = TopScoreDocCollector.create(hitsPerPage);
}

this.searcher.search(booleanQuery,collector);

return collector.topDocs().scoreDocs;
}

/**
* @param whichField
* @param searchString
* @return
* @throws IOException
* @throws ParseException
*/
public Query searchIndexWithWildcardQuery(String whichField, String searchString) throws IOException, ParseException
{
Term term = addTerm(whichField, "*" + searchString + "*");
Query query = new WildcardQuery(term);
return query;
}

/**
* @param whichField
* @param searchString
* @return
*/
public Term addTerm(String whichField, String searchString)
{
Term term = new Term(whichField, searchString);
return term;
}

/**
* @param searchString
* @param operation
* @return
* @throws ParseException
*/
public Query addConditionOpertaion(String searchString, String operation) throws ParseException
{
Query query = null;
if ("and".equals(operation))
{
parser.setDefaultOperator(QueryParser.AND_OPERATOR);
} else if("or".equals(operation)) {
parser.setDefaultOperator(QueryParser.AND_OPERATOR);
}

query = parser.parse(searchString);
return query;
}

/**
* @param booleanQuery <code>BooleanQuery</code>
* @param q <code>Query</code>
* @param type <code>int</code> , 1--> Must, 2-->Should, 3 --> Must Not
*/
public void addQueries(BooleanQuery booleanQuery, Query q, int type)
{
switch(type)
{
case 1: booleanQuery.add(q, Occur.MUST);
break;
case 2: booleanQuery.add(q, Occur.SHOULD);
break;
default:booleanQuery.add(q, Occur.MUST_NOT);
break;
} //End of switch
}

public QueryParser getParser()
{
return parser;
}

public void setParser(String fieldName)
{
this.parser = new QueryParser(fieldName, this.analyzer);
}

public void getDefaultByStatus(int status)
{
this.analyzer = new StandardAnalyzer();
this.parser = new QueryParser("status", this.analyzer);
}

protected void doClear(File dir,boolean deleteSubDir)
{
for (File file: dir.listFiles())
{
if (file.isDirectory() && deleteSubDir)
{
doClear(file,deleteSubDir);
}
file.delete();
}
} //End of doClear();

protected void doClose() throws IOException
{
this.searcher.getIndexReader().close();
}

public boolean add(Object Obj) throws Exception
{
User currentUser = (User)Obj;
boolean isAdded = false;

org.apache.lucene.document.Document luceneDoc = new org.apache.lucene.document.Document();
luceneDoc.add(new IntField("oid", currentUser.getOid(), Field.Store.YES));
luceneDoc.add(new IntField("status", currentUser.getStatus(), Field.Store.YES));
luceneDoc.add(new StringField("login", currentUser.getLogin(), Field.Store.YES));
luceneDoc.add(new StringField("fName", currentUser.getFirstName(), Field.Store.YES));
luceneDoc.add(new StringField("lName", currentUser.getLastName(), Field.Store.NO));
luceneDoc.add(new StringField("email", currentUser.getEmailId(), Field.Store.YES));
luceneDoc.add(new StringField("city", currentUser.getCity(), Field.Store.YES));

// addRelatedFields(luceneDoc,city.getStateCode());

IndexWriter writer = getIndexWriter(false);
writer.addDocument(luceneDoc);

closeIndexWriter();

isAdded = true;
System.out.println(isAdded);
return isAdded;
} // End of add

public boolean update(Object Obj) throws Exception
{
boolean isUpdated = false;
User currentUser = (User) Obj;

org.apache.lucene.document.Document luceneDoc = new org.apache.lucene.document.Document();
// luceneDoc.add(new IntField("oid", currentUser.getOid(), Field.Store.YES));
luceneDoc.add(new IntField("oid", currentUser.getOid(), Field.Store.YES));
luceneDoc.add(new StringField("login", currentUser.getLogin(), Field.Store.YES));
luceneDoc.add(new IntField("status", currentUser.getStatus(), Field.Store.YES));
luceneDoc.add(new StringField("fName", currentUser.getFirstName(), Field.Store.YES));
luceneDoc.add(new StringField("lName", currentUser.getLastName(), Field.Store.NO));
luceneDoc.add(new StringField("email", currentUser.getEmailId(), Field.Store.YES));
luceneDoc.add(new StringField("city", currentUser.getCity(), Field.Store.YES));

// addRelatedFields(luceneDoc,city.getStateCode());

IndexWriter writer = getIndexWriter(false);
writer.updateDocument(new Term("login", currentUser.getLogin()),luceneDoc);
closeIndexWriter();

isUpdated = true;
return isUpdated;
} // End of update

public boolean delete(Object Obj) throws Exception
{
boolean isDeleted = false;
User currentUser = (User) Obj;

Term deleteTerm = new Term("login", currentUser.getLogin());

IndexWriter writer = getIndexWriter(false);
writer.deleteDocuments(deleteTerm); // Or use Query
writer.forceMergeDeletes();
closeIndexWriter();

isDeleted = true;

return isDeleted;
} // End of delete

@Override
public Object search(String[] fieldNames, String[] fieldValues, int returnType, int limit) throws Exception
{
Object obj = null;
org.apache.lucene.search.ScoreDoc[] hits = searchSEO(fieldNames,fieldValues, limit);
int hitSize = (null == hits) ? 0 : hits.length;

System.out.println("total:" + hitSize);

doClose();
return obj;
} // End of search

public void addThreadUser()
{
User user = new User();
addUserPojo(user);
add(user);
}

public void updateThreadUser()
{
User user = new User();
addUserPojo(user);
update(user);
}

public void deleteThreadUser()
{
User user = new User();
addUserPojo(user);
delete(user);
}

private void addUserPojo(User user)
{
user.setOid(3);
user.setLogin("senthil");
user.setFirstName("Semthil");
user.setLastName("Semthil");
user.setStatus(1);
user.setCity("Combiatore");
user.setEmailId("semthil@xyz.com");
}

public void searchUser()
{
searchUser(new String[] {"login"}, new String[] {"Se"}, null);
}

public static void main(String[] args)
{
SearchHelper test = new SearchHelper();
test.searchUser();
}
}

最佳答案

您正在使用StringField 来索引您的数据,但此字段将绕过分析器链,并且总是将您的术语逐字索引为一个标记,而不管您的分析器是什么。如果您想要分析您的数据并且 StandardAnalyzer 已经进行了小写,您应该使用 TextField。除此之外,WildcardQuery 不会 分析它的术语,因此如果您搜索 Banglore,它不会匹配索引中现在小写的 banglore。您必须自己将搜索词小写(或对其使用分析器)。

关于Java Lucene 4.5 如何不区分大小写搜索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30881355/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com