无法使用Lucene.Net访问Azure存储文件夹

时间:2014-05-16 22:33:49

标签: azure azure-storage lucene.net

我们决定在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存储的初学者来说并不是很清楚,所以我们担心我们可能错过了重要的一步。我们检查了连接字符串,但一切似乎都没问题。

3 个答案:

答案 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)

我得到了它的工作。

  • 我刚从GitHub获得了最新版本的AzureDirectory。
  • 获取Azure存储等最新的nuGet包。
  • 重新创建索引。

答案 2 :(得分:0)

除了@brykneval答案(由于声誉低而无法评论): 我尝试了他的解决方案,但是他设置为true的最后一个参数bool compressBlob = false使我的本地调试失败,AzureDirectory库中有404异常,当我发布到Azure Web应用程序时,它有消息System.IO.InvalidDataException: Block length does not match with its complement的异常。

我从构造函数中删除了最后一个参数,一切都像魅力一样。希望这对任何人都有帮助。