遇到麻烦!任何()查询与raven db一起工作

时间:2012-11-20 23:11:34

标签: linq ravendb

我是RavenDB的新手,并且试图让Any()LINQ查询正常工作一直令人沮丧。这是我的文档的样子:

{
  "Key": "BKey",
  "Text": "B Key",
  "IsLocal": false,
  "Category": null,
  "_destroy": false,
  "Translations": [
    {
      "CultureCode": "es-ES",
      "Text": null
    },
    {
     "CultureCode": "ja-JP",
     "Text": "Hello"
    }
  ]
}

我希望以下查询能够为我提供所有没有翻译的条目#es; ES-ES":

var nonTranslatedEntries = 
_docs.Query<ResourceEntry>().Where( e => e.Translations == null || e.Translations.Count == 0 || !e.Translations.Any(t => t.CultureCode == "es-ES" && t.Text != null))

但是,这不起作用。即使存在指定CultureCode的翻译,它也会返回条目。如果我在翻译数组中只有一个项目,它就可以工作。但是只要我在翻译数组中有多个项目,查询就会停止工作。

作为替代解决方案,我尝试执行以下操作:

var translatedEntries =  from re in _docs.Query<ResourceEntry>()
                                    where re.Translations.Any(t => t.CultureCode == cultureCode && t.Text != null)
                                    select new {Id = re.Id};
var translatedIds = translatedEntries.ToList().Select(e => e.Id).ToList();

var nonTranslatedEntries = 
  _docs.Query<ResourceEntry>().Where(e => !e.Id.In(translatedEntryIds));

但这只会带回一个空列表。

非常感谢任何帮助。

谢谢,

尼扎

2 个答案:

答案 0 :(得分:1)

将完成工作的静态索引:

public class Resources_ByTranslation : 
    AbstractIndexCreationTask<ResourceEntry, Resources_ByTranslation.IndexEntry>
{
    public class IndexEntry
    {
        public string Key { get; set; }
        public string CultureCodes { get; set; }
    }

    public Resources_ByTranslation()
    {
        Map = entries => from entry in entries
                         select new {
                                     entry.Key,
                                     CultureCodes = entry.Translations
                                                     .Where(x => x.Text != null)
                                                     .Select(x => x.CultureCode)
                                    };
    }
}

然后查询:

var nonTranslatedEntries =
    session.Query<Resources_ByTranslation.IndexEntry, Resources_ByTranslation>()
           .Where(x => x.CultureCodes != "es-ES")
           .As<ResourceEntry>();

请注意,CultureCodes列表被视为单个字符串。这是由于索引匹配在内部如何工作。这有点奇怪,但确实有效。

答案 1 :(得分:0)

我最终解决了我的问题如下:

创建资源条目后,我继续创建所有可能的翻译并将翻译文本设置为null:

{
  "Key": "BKey",
  "Text": "B Key",
  "IsLocal": false,
  "Category": null,
  "_destroy": false,
  "Translations": [
    {
      "CultureCode": "es-ES",
      "Text": null
    },
    {
     "CultureCode": "ja-JP",
     "Text": null
    }
  ]
}

然后我创建了以下索引:

public class ResourceEntries_ByCultureCodes : AbstractIndexCreationTask<ResourceEntry>
    {
        public ResourceEntries_ByCultureCodes()
        {
            Map = entries => from e in entries
                             select new
                                 {
                                     e.Id,
                                     e.Key,
                                     e.Text,
                                     e.IsLocal,
                                     e.Category,
                                     _ = e.Translations.Select(t => CreateField(t.CultureCode, t.Text != null, false, true))
                                 };
        }
}

这给了我一个平坦的翻译记录,其值设置为&#39; true&#39;如果存在特定文化的翻译。例如,我得到这样的东西:

{ 
   Id,
   Key,
   Text,
   IsLocal,
   Category,
   es-ES: <true> or <false> depending upon whether Translation.Text != null
   ja-JP:<true> or <false> depending upon whether Translation.Text != null
}

然后我可以按照以下方式执行LuceneQuery以获取&#34; es-ES&#34;的所有条目。尚未翻译的内容:

_docs.LuceneQuery<ResourceEntry, ResourceEntries_ByCultureCodes>().WhereEquals("es-ES", false);

我希望有一个更简单的解决方案。