如何确定存储桶中是否存在Couchbase视图? (.NET api)

时间:2012-11-23 20:36:48

标签: c# .net nosql couchbase

目前,当您尝试检索视图后尝试执行查询时,您会发现视图不存在:

var result = _couchClient.GetView<etc>("DocumentName", "ViewNameThatDoesNotExist");
result.Count(); // This returns a service exception

你发现在Count抛出异常后它不存在,所以此刻我使用try / catch来确定是否有异常。

是否有更优雅的解决方案,不需要执行查询所需的资源? 似乎没有像

那样的东西
result.exists()

或类似的东西。

3 个答案:

答案 0 :(得分:2)

我创建了一个重载的CouchbaseClient来解决这个问题。它速度快,效果很好。

编辑:我做了一个小改动,我没有使用string.contains,我使用Json Objects。

public class CouchbaseClientExtended : CouchbaseClient
{
    private string _bucket;
    private bool _isDevMode;
    private CouchbaseCluster _cluster;

    public CouchbaseClientExtended()
    {
        LoadBaseConfig("couchbase");
    }

    public CouchbaseClientExtended(CouchbaseClientConfiguration config) : base(config)
    {
        LoadBaseConfig(config);
    }

    public CouchbaseClientExtended(string sectionName) : base(sectionName)
    {
        LoadBaseConfig(sectionName);
    }

    public CouchbaseClientExtended(ICouchbaseServerPool pool, CouchbaseClientConfiguration config) : base(pool, config)
    {
        LoadBaseConfig(config);
    }

    public CouchbaseClientExtended(string bucketName, string bucketPassword) : base(bucketName, bucketPassword)
    {
        var config = new CouchbaseClientConfiguration
        {
            Bucket = bucketName,
            BucketPassword = bucketPassword
        };
        LoadBaseConfig(config);
        _bucket = bucketName;
    }

    public CouchbaseClientExtended(CouchbaseClientConfiguration config, string bucketName, string bucketPassword) : base(config, bucketName, bucketPassword)
    {
        LoadBaseConfig(config);
        _bucket = bucketName;
    }

    public CouchbaseClientExtended(string sectionName, string bucketName, string bucketPassword)
        : base(sectionName, bucketName, bucketPassword)
    {
        LoadBaseConfig(sectionName);
        _bucket = bucketName;
    }

    private void LoadBaseConfig(string sectionName)
    {
        var config = ConfigurationManager.GetSection(sectionName) as CouchbaseClientSection;
        if (config == null)
        {
            throw new NullReferenceException(
                "Couchbase configuration cannot be null. Add it to App.Config file or pass a custom one via parameter.");
        }
        _bucket = config.Servers.Bucket;
        _isDevMode = config.DocumentNameTransformer.Type == typeof (DevelopmentModeNameTransformer);
        _cluster = new CouchbaseCluster(config);
    }

    private void LoadBaseConfig(CouchbaseClientConfiguration config)
    {
        _bucket = config.Bucket;
        _isDevMode = config.DesignDocumentNameTransformer is DevelopmentModeNameTransformer;
        _cluster = new CouchbaseCluster(config);
    }

    public bool StoreJson<T>(StoreMode storeMode, string key, T value) where T : class
    {
        return Store(storeMode, key, JsonConvert.SerializeObject(value));
    }

    public T GetJson<T>(string key) where T : class
    {
        T obj = null;
        var json = Get<string>(key);
        if (json != null)
        {
            obj = JsonConvert.DeserializeObject<T>(json);
        }
        return obj;
    }

    public bool ViewExist(string designName, string viewName)
    {
        try
        {
            var doc = _cluster.RetrieveDesignDocument(_bucket, designName);
            if (!VerifyDesignDocumentContainsView(doc, viewName))
            {
                if (_isDevMode)
                {
                    var devDoc = _cluster.RetrieveDesignDocument(_bucket, "dev_" + designName);
                    return VerifyDesignDocumentContainsView(devDoc, viewName);
                }
                return false;
            }

            return true;
        }
        catch (WebException wex)
        {
            if (((HttpWebResponse)wex.Response).StatusCode == HttpStatusCode.NotFound)
            {
                return false;
            }
            throw;
        }
    }

    private bool VerifyDesignDocumentContainsView(string doc, string viewName)
    {
        if (string.IsNullOrEmpty(doc) || string.IsNullOrEmpty(viewName))
        {
            return false;
        }

        JToken token;
        JObject jObject = JsonConvert.DeserializeObject<JObject>(doc);
        jObject.TryGetValue("views", out token);
        if (token != null)
        {
            jObject = (JObject)token;
            return jObject.TryGetValue(viewName, out token);
        }
        return false;
    }
}

希望它适合你:)

答案 1 :(得分:1)

马特 - 感谢分享您的扩展方法!看到这个问题现在突然出现了几次,我正在支持1.2.1客户端(将于2013年2月5日发布)。下面的答案在1.2.0中无效,但是预览以供将来参考。我还将它作为答案而不是评论,以便更好地突出代码......

在1.2.1中,将有两种方法来检查不存在的视图。第一种是使用视图的新CheckExists()方法。此方法将查询设计文档并解析JSON。与Matt的方法类似,但不使用CouchbaseCluster API。

var view = client.GetView("designDoc", "viewName")

if (view.CheckExists())
{
  view.Count();
}

第二种方法是捕获有意义类型的异常(不再是InvalidOperationException)。这种方法的优点是减少了一次HTTP查询。

var view = client.GetView("designDoc", "viewName")

try {
    view.Count();
} catch (ViewNotFoundException vnfe) { //extends ViewException
    ...
} catch (ViewException ve) { //bad params for example
   log.Error("Error {0}, Reason {1}", ve.Error, ve.Reason);
} catch (Exception e) {
   ...
}

Jira请求位于http://www.couchbase.com/issues/browse/NCBC-165,代码正在http://review.couchbase.org/#/c/24068/1进行审核。

答案 2 :(得分:0)

您可以尝试使用Design REST API,但不确定它是否更优雅,请参阅 http://www.couchbase.com/docs/couchbase-manual-2.0/couchbase-views-designdoc-api-retrieving.html

这种方法是一种非常通用的方法。

我不是.Net专家,但在调用getView()方法时在Java SDK中,如果视图没有退出,则引发异常。也许你在.Net中有类似的方式