0

我正在一个网站上工作,我需要存储用户撰写的所有文章。每当特定用户输入关键字时,我都需要搜索与该关键字相关的文章。现在正在使用 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”等时,实际上需要更多时间进行搜索

4

1 回答 1

3

我没有尝试将 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 个文档的模糊搜索。

于 2013-05-28T11:14:31.727 回答