使用 Lucene.NET 限制数据
Limiting Data With Lucene.NET
我们正在使用 Sql Server 2012 全文索引,但是我们想将我们的数据库移动到 Sql Azure。使用迁移工具它告诉我们全文索引与 Sql Azure 不兼容(即使是预览版的 v12 也不支持它,所以看起来他们并不打算支持它)。
因此,我们正在寻找替代方案,目前我发现的最佳方案是将 Lucene.NET 与 AzureDirectory (https://azuredirectory.codeplex.com) 结合使用。这将允许我们将索引存储在 blob 存储中,并将其缓存在托管网站(也在 Azure 中)的 VM 的本地文件系统上。
我们遇到的问题是,我们打算索引的数据是诸如新闻报道之类的项目,由于我们的发布模型限制项目仅对一部分用户可见,因此所有用户都看不到这些项目.在搜索新闻报道时使用全文索引,我们可以通过简单地连接对他们可见的内容来限制使用搜索的数据,但是使用 Lucene 我们将无法做到这一点。
我们提出的想法是在索引中获取新闻故事,其中包含允许查看该新闻故事的一组 UserId,恐怕我对 Lucene 很陌生,我无法找到最好的方法为此,我们正在为这样的新闻故事添加索引:
document.Add(new Field("Title",
news.Title,
Field.Store.YES,
Field.Index.ANALYZED,
Field.TermVector.NO));
document.Add(new Field("Content",
news.Content,
Field.Store.YES,
Field.Index.ANALYZED,
Field.TermVector.NO));
但是,如果我们有一个定义为
的用户 ID 集合
IEnumerable<int>
我们如何将这些添加到新闻故事索引中,然后有效地搜索给定的用户 ID。此外,如果我们针对 lucene 文档添加 100 或 1000 的 UserId,性能会受到什么影响。有没有比沿着这条路走更好的方法,因为这可能是一个糟糕的主意(可能是一个糟糕的主意)?
我在迁移到 Azure 时也 运行 遇到了这个问题,最终得到了相同的权限模型。由于您的 userIds 是整数并且不会有特殊字符,因此您可以依赖许多 Lucene(.net) 分析器,例如 StandardAnalyzer 和 WhitespaceAnalyzer 来将 ID 列表拆分为术语,只要您输入一个细绳。只需使用 space 或逗号分隔每个 ID,具体取决于分析器将拆分的内容。
您应该能够像这样简单地为 ID 编制索引...
IEnumerable<int> userIds = new int[] { 123, 456, 789 };
document.Add(new Field("AllowedUserIDs",
String.Join(" ", userIds),
Field.Store.NO,
Field.Index.ANALYZED_NO_NORMS));
然后确保使用 TermQuery 进行查询以匹配整个术语 (ID)。像...
int currentUserID = 123;
string queryString = "airplane";
BooleanQuery query = new BooleanQuery();
query.Add(new TermQuery(new Term("AllowedUserIDs", currentUserID.ToString())), Occur.MUST);
query.Add(new TermQuery(new Term("Title", queryString)), Occur.SHOULD);
query.Add(new TermQuery(new Term("Content", queryString)), Occur.SHOULD);
我不能非常具体地谈论性能问题,但我们的列表中有几百个 ID,自从我们添加它以来它似乎没有影响查询时间。真的跟搜几百几千字的新闻文章没什么区别
我们正在使用 Sql Server 2012 全文索引,但是我们想将我们的数据库移动到 Sql Azure。使用迁移工具它告诉我们全文索引与 Sql Azure 不兼容(即使是预览版的 v12 也不支持它,所以看起来他们并不打算支持它)。
因此,我们正在寻找替代方案,目前我发现的最佳方案是将 Lucene.NET 与 AzureDirectory (https://azuredirectory.codeplex.com) 结合使用。这将允许我们将索引存储在 blob 存储中,并将其缓存在托管网站(也在 Azure 中)的 VM 的本地文件系统上。
我们遇到的问题是,我们打算索引的数据是诸如新闻报道之类的项目,由于我们的发布模型限制项目仅对一部分用户可见,因此所有用户都看不到这些项目.在搜索新闻报道时使用全文索引,我们可以通过简单地连接对他们可见的内容来限制使用搜索的数据,但是使用 Lucene 我们将无法做到这一点。
我们提出的想法是在索引中获取新闻故事,其中包含允许查看该新闻故事的一组 UserId,恐怕我对 Lucene 很陌生,我无法找到最好的方法为此,我们正在为这样的新闻故事添加索引:
document.Add(new Field("Title",
news.Title,
Field.Store.YES,
Field.Index.ANALYZED,
Field.TermVector.NO));
document.Add(new Field("Content",
news.Content,
Field.Store.YES,
Field.Index.ANALYZED,
Field.TermVector.NO));
但是,如果我们有一个定义为
的用户 ID 集合IEnumerable<int>
我们如何将这些添加到新闻故事索引中,然后有效地搜索给定的用户 ID。此外,如果我们针对 lucene 文档添加 100 或 1000 的 UserId,性能会受到什么影响。有没有比沿着这条路走更好的方法,因为这可能是一个糟糕的主意(可能是一个糟糕的主意)?
我在迁移到 Azure 时也 运行 遇到了这个问题,最终得到了相同的权限模型。由于您的 userIds 是整数并且不会有特殊字符,因此您可以依赖许多 Lucene(.net) 分析器,例如 StandardAnalyzer 和 WhitespaceAnalyzer 来将 ID 列表拆分为术语,只要您输入一个细绳。只需使用 space 或逗号分隔每个 ID,具体取决于分析器将拆分的内容。
您应该能够像这样简单地为 ID 编制索引...
IEnumerable<int> userIds = new int[] { 123, 456, 789 };
document.Add(new Field("AllowedUserIDs",
String.Join(" ", userIds),
Field.Store.NO,
Field.Index.ANALYZED_NO_NORMS));
然后确保使用 TermQuery 进行查询以匹配整个术语 (ID)。像...
int currentUserID = 123;
string queryString = "airplane";
BooleanQuery query = new BooleanQuery();
query.Add(new TermQuery(new Term("AllowedUserIDs", currentUserID.ToString())), Occur.MUST);
query.Add(new TermQuery(new Term("Title", queryString)), Occur.SHOULD);
query.Add(new TermQuery(new Term("Content", queryString)), Occur.SHOULD);
我不能非常具体地谈论性能问题,但我们的列表中有几百个 ID,自从我们添加它以来它似乎没有影响查询时间。真的跟搜几百几千字的新闻文章没什么区别