3
votes

please advise me on how to correctly conduct a full-text search on a dictionary field.

I have indexed all translatable fields like this:

public class TranTest
{
    public string Id { get; set; }
    public IDictionary<string, string> Trans1 { get; set; }
    public IDictionary<string, string> Trans2 { get; set; }

    //for index queries
    public IDictionary<string, string> Trans { get; set; }
}

public class TranTestIndex : AbstractIndexCreationTask<TranTest>
{
    public TranTestIndex()
    {
        Map = docs =>
            from doc in docs
            select new
            {
                _ = doc.Trans1.Select(x => CreateField("Trans_" + x.Key, x.Value)),
                Trans2 = doc.Trans2.Select(x => CreateField("Trans_" + x.Key, x.Value)),
                /* etc. */
            };

        Index("Trans_en", FieldIndexing.Analyzed);
        Index("Trans_fi", FieldIndexing.Analyzed);
        /* etc. */
    }
}

This (query translates to: Trans_en:(term)) returns correct results:

var luceneQ = session.Advanced.LuceneQuery<TranTest, TranTestIndex>().Search(x => x.Trans["en"], searchTerms).ToList();

But I would prefer using the IRavenQueryable API. Unfortunately a similiar query in that API produces InvalidOperationException: Could not understand how to translate 'x.Trans.get_Item("en")' to a RavenDB query:

var ravenQ = session.Query<TranTest, TranTestIndex>().Search(x => x.Trans["en"], searchTerms);
results = ravenQ.ToList();  //Exception!

Which is odd, considering this works flawlessly (translates to: Trans_en:"term*"):

session.Query<TranTest, TranTestIndex>().Where(x => x.Trans["en"].StartsWith(searchTerms))

My questions regarding this issue:

  1. How would I create a multiple term full-text search query on a dictionary field with IRavenQueryable linq API?
  2. Is it possible to combine IRavenQueryable and IDocumentQuery into one query?
  3. Is there a another/better way to create the index?
    • It has to support dynamically adding new languages
    • It has to support searching over a concrete language
    • Search should be conducted over multiple fields
1

1 Answers

1
votes

You've discovered a bug. I've verified with these unit tests, and submitted it to the RavenDB issue tracker.

To workaround for now, either use the Lucene query approach, or (as you alluded to in your second question) you can customize the underlying DocumentQuery of the IRavenQueryable as follow:

session.Query<TranTest, TranTestIndex>()
       .Customize(x => ((IDocumentQuery<TranTest>) x)
                           .Search(q => q.Trans["en"], searchTerms))