【问题标题】:How do i implement tag searching? with lucene?如何实现标签搜索?用lucene?
【发布时间】:2011-01-27 03:16:48
【问题描述】:

我没有用过 lucene。上次我问(几个月前,也许一年)人们建议使用 lucene。如果我不应该使用 lucene 我应该使用什么?例如说有这样标记的项目

  1. 苹果胡萝卜
  2. 苹果
  3. 胡萝卜
  4. 苹果香蕉

如果用户搜索苹果,我不在乎 1,2 和 4 是否有任何偏好。但是我看到很多论坛都这样做,我讨厌的是当用户搜索苹果胡萝卜 2 和 3 时结果很高,而 1 很难即使它与我的搜索更接近也要找到。

我还希望能够搜索胡萝卜-苹果,这只会让我得到 3。我不确定如果我搜索胡萝卜香蕉会发生什么,但无论如何只要标记为 2 和 3 结果的更多项目排名较低然后 1 当我搜索苹果胡萝卜时,我会很高兴。

lucene 能做到这一点吗?我从哪里开始?我尝试查找它,当我这样做时,我会看到很多课程,并且会看到有关文档,网页的教程,但是当我喜欢标记某些东西时,没有人清楚该做什么。如果不是 lucene 我应该用什么来标记?

【问题讨论】:

  • Lucene 非常适合执行此操作。如果您希望 apple 和 apples(复数)匹配,您只需要在索引和查询索引时注意使用正确的语言词干分析器即可。
  • 1,2 和 4 在关键字 apple 上的排名(假设您将使用词干分析器来处理复数)不同,因为排名算法会计算该术语在该字段中的相对权重。在案例 2 中,您有 1 次命中,并且字段长度 = 1。在案例 1 和 4 中,您在 2-term 字段中有 1 次命中。粗略地说,这些点击的权重会相差 2 倍。

标签: c# .net lucene lucene.net tagging


【解决方案1】:

.net 的 Lucene 似乎已经成熟。无需使用 Java 或 SOLR

Standard query language for Lucene 允许同等排名的搜索词和否定词

因此,如果您的 Lucene 索引有一个字段“标签”,您的查询将是

tag:apple* OR tag: carrot*

这将为每个单词提供相同的排名,并为带有两个标签的文档提供更多的排名权重

要否定标签,请使用此

tag:carrot* NOT tag:apple*

使用 Lucene here 显示索引和查询的简单示例

【讨论】:

  • 谢谢:)。我希望更多的人继续这样做(我真的需要帮助!)
  • 本教程看起来不错,查询链接看起来很有用。我怀疑我会在一天结束之前搞砸这个。
  • 这里(对我而言)重要的是标签是否存在多对多关系。即单个项目可以有多个“标签”字段。恕我直言,这就是标签的力量所在。我不想将标签存储为单个单词的字符串,即'''一二三''',并且必须搜索''''''。
【解决方案2】:

编辑: 您可以使用 Lucene。以下是如何在 Lucene.net 中执行此操作的说明。 一些 Lucene 基础知识是:

  • Document - 是 Lucene 中的存储单元。它有点类似于数据库记录。
  • Field - Lucene 中的搜索单元。类似于数据库列。 Lucene 通过查询和匹配字段来搜索文本。应为字段编制索引以启用搜索。
  • Token - Lucene 中的搜索原子。通常是一个词,有时是一个短语、字母或数字。
  • 分析器 - Lucene 将字段转换为标记的部分。

请阅读 this blog post 关于创建和使用 Lucene.net 索引的信息。

我假设您正在标记博客文章。如果我完全错了,请直说。 为了搜索标签,您需要将它们表示为 Lucene 实体,即作为“标签”字段中的标记。

这样做的一种方法是为每篇博文分配一个 Lucene 文档。 该文档将至少包含以下字段:

  • id:博文的唯一 ID。
  • 内容:博文的文本。
  • 标签:标签列表。

索引:每当您向帖子添加标签、删除标签或对其进行编辑时,您都需要为帖子编制索引。分析器会将字段转换为它们的标记表示。

Document doc = new Document();
doc.Add(new Field("id", i.ToString(), Field.Store.YES, Field.Index.NO));
doc.Add(new Field("content", text, Field.Store.YES, Field.Index.TOKENIZED));
doc.Add(new Field("tags", tags, Field.Store.YES, Field.Index.TOKENIZED));
writer.AddDocument(doc);

剩下的部分是检索。为此,您需要创建一个QueryParser 并向其传递一个查询字符串,如下所示:

QueryParser qp = new QueryParser();
Query q = qp.Parse(s);
Hits = Searcher.Search(q);

s 需要的语法是:

tags: apples tags: carrots

搜索苹果或胡萝卜

tags: carrots NOT tags: apples

有关构建 s 的详细信息,请参阅Lucene Query Parser Syntax

【讨论】:

  • 很好的答案。太糟糕了,我睡过头了,直到赏金结束才去。添加搜索似乎没有我最初想的那么糟糕。
  • 不错的答案 - 实现“标签”的正确方法是一个重要问题 - 因为有很多(错误的?痛苦的慢?)方法可以做到这一点,而标签/民间分类法的想法是留在这里(即支持分层分类法)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-07
  • 2021-08-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多