我正在开发一个网站,我需要存储用户撰写的所有文章。每当特定用户输入关键字时,我需要搜索与该关键字相关的文章。现在正在使用 Neo4j Lucene 索引对所有文章的文章内容进行索引,如下所示
ArticleContentIndex += (article_node,"article_data",a_data)
并根据如下关键字搜索文章
val article_content_index = getNodeIndex("article_content").get
val w = "*"+word+"*"
val articles = article_content_index.query("article_data",w).iterator()
随着文章数量的增加,这种方法会花费更多时间。有没有更好的方法来做到这一点?
编辑:每当搜索关键字包含最常见的单词(例如“the”、“is”、“a”等)时,实际上会花费更多时间进行搜索
最佳答案
我没有尝试将 Neo4j 与 lucene 一起使用,但作为替代方案,您可以使用 RAMDirectory。
val analyzer = new StandardAnalyzer(Version.LUCENE_43)
val index = new RAMDirectory()
val config = new IndexWriterConfig(Version.LUCENE_43, analyzer)
然后在 Lucene 启动时,您可以将数据添加到索引中:
mkIndex(xs: Iterable[Articles])
索引包含文档:
def mkIndex(xs: Iterable[Articles]) {
def withWriter[T](f: IndexWriter => T): T = {
val iw = new IndexWriter(index, config)
Try(f(iw)) match {
case Success(_) => iw.close()
case Failure(e) => // do something with exception
}
withWriter { _.addDocuments(xs.map(mkDoc)) }
}
所以我们需要制作一个文档:
def mkDoc(art: Article): Document = make(new Document) { doc =>
doc add TextField("id", art.id.toString)
doc add TextField("data", art.content)
doc add TextField("author", art.author)
}
因此,当索引准备好后,您需要一个搜索功能:
/**
* id - your article ID,
* field - the default field for query terms
* lim - limit results
*/
def search(id: String, field: String, lim: Int): Seq[Article] = {
val reader = DirectoryReader.open(index)
val searcher = new IndexSearcher(reader)
val collector = TopScoreDocCollector.create(lim, true)
val q = new QueryParser(Version.LUCENE_43, field, analyzer).parse(id)
searcher.search(q, collector)
val hits = collector.topDocs().scoreDocs
val results = hits map { hit => searcher doc hit.doc }
reader.close()
results map { doc => Article(doc.get("id"), doc.get("data"), doc.get("author")) }
}
使用此搜索功能,您可以进行模糊搜索或通配符搜索。
这不是使用 Neo4j 最佳实践的直接答案,而是另一种观点。它在小型 AWS 机器上不到一秒的时间内完成了 50k 文档的模糊搜索。
关于java - 使用 java/scala API 进行 Neo4j lucene 搜索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16787593/