问题
I have some code that is searching a RavenDB database with the following index:
public class Products_Search :
AbstractIndexCreationTask<Product, Products_Search.Result>
{
public class Result
{
public string Query { get; set; }
}
public Products_Search()
{
Map = products =>
from product in products
select new
{
Query = new
{
Categories = product.Categories.Boost(5),
Brands = product.Brands.Boost(8),
product.Description,
Name = product.Name.Boost(10),
product.SKU
},
product.Price
};
Index(x => x.Query, FieldIndexing.Analyzed);
}
}
If I query against this like this (both strawberry protein are spelt wrong):
var query = RavenSession.Query<Products_Search.Result, Products_Search>()
.Where(x => x.Query == "strawbery protien");
var suggestions = query.Suggest().Suggestions.Take(5)
I would like the suggestions be be "strawberry protein" not one of "strawberry" and another of "protein". Is this possible with RavenDB?
回答1:
I have to do something similar and I use the LuceneQuery
syntax to achieve it. I am using the OR
operator but you will want to use the AND
operator.
The Index
public class ContentItem_BySearchParam : AbstractIndexCreationTask<ContentItem>
{
public ContentItem_BySearchParam()
{
Map = contentItems =>
from contentItem in contentItems
select new {contentItem.Title, contentItem.Description, contentItem.Keywords};
Store("Title", FieldStorage.Yes);
Index("Title", FieldIndexing.Analyzed);
Store("Description", FieldStorage.Yes);
Index("Description", FieldIndexing.Analyzed);
Store("Keywords", FieldStorage.Yes);
Index("Keywords", FieldIndexing.Analyzed);
}
}
The Query
public SearchResults GetResults(IDocumentSession db, params string[] searchTerms)
{
var query =
GetLuceneQuery("Title", searchTerms) + " OR " +
GetLuceneQuery("Description", searchTerms) + " OR " +
GetLuceneQuery("Keywords", searchTerms);
var results = db
.Advanced
.LuceneQuery<ContentItem, RavenIndexes.ContentItem_BySearchParam>()
.Where(query)
.ToList();
.... do other stuff
}
private string GetLuceneQuery(string field, string[] terms, string searchOperator = "")
{
var join = " " + searchOperator;
var prefix = field + ":(" + searchOperator;
return prefix + String.Join(@join, terms) + ")";
}
回答2:
ilivewithian,
We build the suggestions based on the terms that we use. You can index the Query field twice, once using Analyzed (in which case it breaks it into words) and once using default, in which case it uses the full term. That might give you what you want.
来源:https://stackoverflow.com/questions/10935048/ravendb-query-suggest-multiple-words