1

私は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」の翻訳がないすべてのエントリが表示されると思います。

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の翻訳が存在する場合でも、エントリが返されます。translations配列内にアイテムが1つしかない場合に機能します。しかし、translations配列内に複数のアイテムがあるとすぐに、クエリは機能しなくなります。

別の解決策として、私は次のことを試みました。

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));

しかし、それは空のリストを戻すだけです。

どんな助けでも大歓迎です。

ありがとう、

ニザール

4

2 に答える 2

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リストは単一の文字列として扱われていることに注意してください。これは、インデックスマッチングが内部でどのように機能するかによるものです。少し奇妙ですが、機能します。

于 2012-11-21T16:56:02.353 に答える
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))
                                 };
        }
}

その特定のカルチャに翻訳が存在する場合、値が「true」に設定された翻訳のフラットなレコードが得られます。たとえば、次のようなものが返されます。

{ 
   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を実行して、翻訳されていない「es-ES」のすべてのエントリを取得できます。

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

しかし、もっと簡単な解決策があればいいのにと思います。

于 2012-11-22T16:22:40.233 に答える