Advanced Queries

66 views
Skip to first unread message

Troy

unread,
Jun 16, 2012, 3:54:23 AM6/16/12
to rav...@googlegroups.com
Hello, I need to do a search like: Query = "my product title" OR blue OR brown AND Department = Electronics
 
A user would enter in a textbox the search as:          "my product title" blue brown           ---- I would add the specific part of the query by Department the user was browsing so they would not enter that in the textbox.
 
This woul equate to a "phrase search" and then an OR search on the rest of the search terms.
 
Can this be done in one query? Should this use a LuceneQuery?
 
Is there a place to understand when to use LucenQuery, Search() or Where() ... etc... I see bits here and there, but hard to find an example when you need it.
 
I created an index like:
 
public class Product_Search : AbstractIndexCreationTask<Product, Product_Search.SearchResult> {
    public class SearchResult {
      public string Query { get; set; }
      public DateTimeOffset Created { get; set; }
      public string Department { get; set; }
    }
    public Product_Search() {
      Map = products =>
        from product in products
        select new {
          Query = new object[]
          {
            product.Title,
            product.Category,
            product.Color
          },
          product.Created,
          product.Deparment
        };
      Index( x => x.Query, FieldIndexing.Analyzed );
    }
  }
 
Also, I would need a case-insensitive search as well. Am I going in the right direction? If the index is correct, what is the correct way to query this? LuceneQuery, using the Index and .Search(), etc.?
 
Thanks a bunch!
Troy

Itamar Syn-Hershko

unread,
Jun 17, 2012, 4:12:20 AM6/17/12
to rav...@googlegroups.com
The default query parsing done by RavenDB is ORing the clauses, so when you search with the Search operator on an analyzed field, you will get the effect you are looking for.

To add the Department clause, you can use either the Linq provider or the LuceneQuery API.

The Linq API is very easy to work with, but sometimes you need to construct complex queries, and this is what the LuceneQuery is there for.

All searches using default analyzed or non-analyzes fields are case insensitive

Oren Eini (Ayende Rahien)

unread,
Jun 17, 2012, 4:13:39 AM6/17/12
to rav...@googlegroups.com
Troy,
I would do this using:

session.Advanced.LuceneQuery<Product>()
   .UseDefaultField("Query")
   .Where(userQuery)
   .AndAlso()
   .WhereEquals("Department", "electronics")
   .ToList();

This would generate the right query (1.2, mind) for you.

On Sat, Jun 16, 2012 at 10:54 AM, Troy <tza...@gmail.com> wrote:

Troy

unread,
Jun 17, 2012, 1:35:34 PM6/17/12
to rav...@googlegroups.com
Sweet, thanks Oren and Itamar, this is perfect. I am developing against 1.2 as I am using the WebApi RC so this is perfect!
 

On Sunday, June 17, 2012 4:13:39 AM UTC-4, Oren Eini wrote:
Troy,
I would do this using:

session.Advanced.LuceneQuery<Product>()
   .UseDefaultField("Query")
   .Where(userQuery)
   .AndAlso()
   .WhereEquals("Department", "electronics")
   .ToList();

This would generate the right query (1.2, mind) for you.

Troy

unread,
Jun 17, 2012, 4:04:12 PM6/17/12
to rav...@googlegroups.com
What Namespace does UseDefaultField() extension live in? Or maybe I am missing a Nuget Package, I have RavenDB.Client 1.2.2017-Unstable installed... and cannot seem to find it.

Troy

unread,
Jun 17, 2012, 4:13:50 PM6/17/12
to rav...@googlegroups.com
Actually, I think I found it.. it is:
UsingDefaultField
not
UseDefaultField
Is that Correct?

Oren Eini (Ayende Rahien)

unread,
Jun 18, 2012, 1:34:30 AM6/18/12
to rav...@googlegroups.com
Yes

Troy

unread,
Jun 21, 2012, 1:02:54 PM6/21/12
to rav...@googlegroups.com
I have seem to run across two issues...
 
Issue 1:
A. If you have a phrase search then a term, it seems to find something.
B. If you simply put the term first, then the phrase, it fails to find the same record.
 
Issue 2:
A: If you do a phrase search and a term, it finds as expected.
B: Do the same phrase search and enter a different term, it finds as expected.
C: Do the same phrase search and enter the two terms from the above, it finds nothing.
 
I have attached two failing tests, one for each issue... It "sort of" seems to be doing an AND search, not an OR search... however since in these cases the phrase does not actually ever match, it seems to do an OR between the phrase and a single term.
ProductTests.cs

Oren Eini (Ayende Rahien)

unread,
Jun 21, 2012, 2:49:57 PM6/21/12
to rav...@googlegroups.com
Issue 1 & 2 are the result of the same problem, let us look at your queries:
The 1st generates:
"Gigabit Switch Network" Vertical AND Department:Electronics

The 2nd generates:
Vertical "Gigabit Switch Network" AND Department:Electronics

Looking at this, it should be obvious what is going on, you are missing () in this, so the AND binds to the left most part.

This works:

results = session.Advanced.LuceneQuery<Product, Product_Search>()
 .UsingDefaultField("Query")
 .OpenSubclause()
 .Where("Vertical \"Gigabit Switch Network\"") // <-- Only difference from above successful test, is putting the single term in front of phrase
 .CloseSubclause()
 .AndAlso()
 .WhereEquals("Department", "Electronics")
 .WaitForNonStaleResults()
 .Statistics(out stats);

Troy

unread,
Jun 21, 2012, 3:36:41 PM6/21/12
to rav...@googlegroups.com
Confirmed! Thanks, this newbie learned something new today.
 
Thanks Oren!
Reply all
Reply to author
Forward
0 new messages