我们决定在ServiceStack中开发的API中实现搜索功能,我们决定使用Lucene.Net,因为我们听说它是一个很棒的索引器来进行搜索。
我们创建了一个辅助角色,其职责是在Azure存储文件夹中创建索引,我们使用Leon Cullen's tutorial引导自己。我们使用该帖子中指定的AzureDirectory library,因此我们可以使用最新的Azure SDK。
然后在我们的API项目中我们添加了Lucene.Net和AzureDirectory的引用,我们的端点最终看起来像这样:
public object Post(SearchIndex request)
{
List<Product> products = new List<Product>();
var pageSize = -1;
var totalpages = -1;
int.TryParse(ConfigurationManager.AppSettings["PageSize"], out pageSize);
if (request.Page.Equals(0))
{
request.Page = 1;
}
// Get Azure settings
AzureDirectory azureDirectory ;
try
{
// This is the line where we get the Access denied exception thrown at us
azureDirectory = new AzureDirectory(Microsoft.WindowsAzure.Storage.CloudStorageAccount.Parse(ConfigurationManager.AppSettings["ConnectionStringAzureSearch"]), "indexsearch");
IndexSearcher searcher;
using (new AutoStopWatch("Creating searcher"))
{
searcher = new IndexSearcher(azureDirectory);
}
using (new AutoStopWatch(string.Format("Search for {0}", request.SearchString)))
{
string[] searchfields = new string[] { "Id", "Name", "Description" };
var hits = searcher.Search(QueryMaker(request.SearchString, searchfields), request.Page * pageSize);
int count = hits.ScoreDocs.Count();
float temp_totalpages = 0;
temp_totalpages = (float)hits.ScoreDocs.Count() / (float)pageSize;
if (temp_totalpages > (int)temp_totalpages)
{
totalpages = (int)temp_totalpages + 1;
}
else
{
totalpages = (int)temp_totalpages;
}
foreach (ScoreDoc match in hits.ScoreDocs)
{
Document doc = searcher.Doc(match.Doc);
int producId = int.Parse(doc.Get("Id"));
Product product = Db.Select<Product>("Id={0}", producId).FirstOrDefault();
products.Add(product);
}
}
return new SearchIndexResult { result = products.Skip((int)((request.Page - 1) * 10)).Take(pageSize).ToList(), PageSize = pageSize, TotalPages = totalpages };
}
catch (Exception e)
{
return new HttpResult(HttpStatusCode.NoContent, "azureDirectory. Parameter: " + request.SearchString + ". e: " + e.Message);
}
}
如果我们在本地运行它,它按预期工作,返回我们期望的结果。但是,当我们将API发布到Azure并尝试访问搜索端点时,我们收到了403错误消息,其中包含“访问路径&#34; D:/ AzureDirectory&#34;被拒绝&#34;。
我们很困惑为什么要尝试访问这样的文件夹,文件夹的名称是错误的,我认为它试图访问本地路线,我们真的不喜欢&#39;知道为什么它在本地工作正常,但一旦部署到Azure,它就会停止工作。
辅助角色运行没有问题,但它是无法访问Azure存储中文件夹的API端。我们是否遗漏了配置中的一些重要步骤?我们遵循的教程对于使用Lucene.Net或Azure存储的初学者来说并不是很清楚,所以我们担心我们可能错过了重要的一步。我们检查了连接字符串,但一切似乎都没问题。
答案 0 :(得分:1)
至于参考: https://github.com/azure-contrib/AzureDirectory/blob/master/AzureDirectory/AzureDirectory.cs
当你这样做时
azureDirectory = new AzureDirectory(Microsoft.WindowsAzure.Storage.CloudStorageAccount.Parse(ConfigurationManager.AppSettings["ConnectionStringAzureSearch"]), "indexsearch");
执行
var cachePath = Path.Combine(Path.GetPathRoot(Environment.SystemDirectory), "AzureDirectory");
var azureDir = new DirectoryInfo(cachePath);
if (!azureDir.Exists)
azureDir.Create();
var catalogPath = Path.Combine(cachePath, _containerName);
var catalogDir = new DirectoryInfo(catalogPath);
if (!catalogDir.Exists)
catalogDir.Create();
_cacheDirectory = FSDirectory.Open(catalogPath);
对您而言,这么简单的解决方案可能是在站点根目录上拥有该目录
DirectoryInfo info = new DirectoryInfo(HostingEnvironment.MapPath("~/"));
azureDirectory = new AzureDirectory(storageAccount, containerName, new SimpleFSDirectory(info), true);
答案 1 :(得分:0)
我得到了它的工作。
答案 2 :(得分:0)
除了@brykneval答案(由于声誉低而无法评论):
我尝试了他的解决方案,但是他设置为true的最后一个参数bool compressBlob = false
使我的本地调试失败,AzureDirectory库中有404异常,当我发布到Azure Web应用程序时,它有消息System.IO.InvalidDataException: Block length does not match with its complement
的异常。
我从构造函数中删除了最后一个参数,一切都像魅力一样。希望这对任何人都有帮助。