NEST C# - elasticsearch - 电子商务过滤器组合

Nes*_*sse 3 c# filter e-commerce elasticsearch nest

我正在尝试将弹性搜索应用到我的网上商店,但在使用过滤器方面遇到了一些麻烦.过滤是动态完成的.

例:

我首先展示了所有被索引的产品.所以没有应用过滤器.访客可以选择自己的过滤器,如:颜色,尺寸,品牌,类型,类别,....

但我现在不知道如何使用elasticsearch和NEST构建搜索结果.

这是我没有过滤的解决方案:

var query = ElasticClient.Search<Product>(s => s
            .From(from)
            .Size(size)
        );
Run Code Online (Sandbox Code Playgroud)

我还有另一个关于索引集合<>或列表<>的问题.我不得不在这些集合上使用JsonIgnore.我可以索引那些吗?

这是我的班级:

/// <summary>
/// Represents a product
/// </summary>
public partial class Product    {

    private ICollection<ProductCategory> _productCategories;
    private ICollection<ProductManufacturer> _productManufacturers;
    private ICollection<ProductPicture> _productPictures;


    /// <summary>
    /// Gets or sets the name
    /// </summary>
    public virtual string Name { get; set; }

    /// <summary>
    /// Gets or sets the short description
    /// </summary>
    public virtual string ShortDescription { get; set; }


    /// <summary>
    /// Gets or sets a value indicating whether the entity is published
    /// </summary>
    public virtual bool Published { get; set; }

    /// <summary>
    /// Gets or sets a value indicating whether the entity has been deleted
    /// </summary>
    public virtual bool Deleted { get; set; }

    /// <summary>
    /// Gets or sets the date and time of product creation
    /// </summary>
    public virtual DateTime CreatedOnUtc { get; set; }

    /// <summary>
    /// Gets or sets the date and time of product update
    /// </summary>
    public virtual DateTime UpdatedOnUtc { get; set; }



    /// <summary>
    /// Gets or sets the collection of ProductCategory
    /// </summary>
    [JsonIgnore] /* added - wesley */
    public virtual ICollection<ProductCategory> ProductCategories
    {
        get { return _productCategories ?? (_productCategories = new List<ProductCategory>()); }
        protected set { _productCategories = value; }
    }

    /// <summary>
    /// Gets or sets the collection of ProductManufacturer
    /// </summary>
    [JsonIgnore] /* added - wesley */
    public virtual ICollection<ProductManufacturer> ProductManufacturers
    {
        get { return _productManufacturers ?? (_productManufacturers = new List<ProductManufacturer>()); }
        protected set { _productManufacturers = value; }
    }

    /// <summary>
    /// Gets or sets the collection of ProductPicture
    /// </summary>
    [JsonIgnore] /* added - wesley */
    public virtual ICollection<ProductPicture> ProductPictures
    {
        get { return _productPictures ?? (_productPictures = new List<ProductPicture>()); }
        protected set { _productPictures = value; }
    }


}
Run Code Online (Sandbox Code Playgroud)

有人可以帮助我吗?

Mar*_*man 8

请务必阅读有关编写查询的完整文档:http://nest.azurewebsites.net/nest/writing-queries.html

接下来是从那里粘贴的摘录.

无条件查询

编写复杂的布尔查询是一回事,但更常见的是,您不希望根据用户输入来决定如何进行查询.

public class UserInput
{
    public string Name { get; set; }
    public string FirstName { get; set; }
    public int? LOC { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后

.Query(q=> {
    QueryDescriptor<ElasticSearch> query = null;
    if (!string.IsNullOrEmpty(userInput.Name))
        query &= q.Term(p=>p.Name, userInput.Name);
    if (!string.IsNullOrEmpty(userInput.FirstName))
        query &= q
            .Term("followers.firstName", userInput.FirstName);
    if (userInput.LOC.HasValue)
        query &= q.Range(r=>r.OnField(p=>p.Loc).From(userInput.Loc.Value))
    return query;
})
Run Code Online (Sandbox Code Playgroud)

这又一次变得乏味和冗长.因此,nest允许您将以前的查询编写为:

.Query(q=>
    q.Term(p=>p.Name, userInput.Name);
    && q.Term("followers.firstName", userInput.FirstName)
    && q.Range(r=>r.OnField(p=>p.Loc).From(userInput.Loc))
)
Run Code Online (Sandbox Code Playgroud)

如果任何查询导致空查询,则不会将其发送到elasticsearch.

因此,如果userInput上的所有术语都为null(或空字符串),除了userInput.Loc,它甚至不会将范围查询包装在布尔查询中,而只是发出一个普通范围查询.

如果所有这些都为空,则会产生match_all查询.

默认情况下会启用此无条件行为,但可以像这样调整:

 var result = client.Search<ElasticSearchProject>(s=>s
    .From(0)
    .Size(10)
    .Strict() //disable conditionlessqueries by default
    ///EXAMPLE HERE
);
Run Code Online (Sandbox Code Playgroud)

但是查询本身可以选择重新进入或退出.

.Query(q=>
    q.Strict().Term(p=>p.Name, userInput.Name);
    && q.Term("followers.firstName", userInput.FirstName)
    && q.Strict(false).Range(r=>r.OnField(p=>p.Loc).From(userInput.Loc))
)
Run Code Online (Sandbox Code Playgroud)

在此示例中,如果userInput.Name为null或为空,则将导致DslException.无论SearchDescriptor是否使用.Strict(),范围查询都将使用无条件逻辑.

另外值得注意的是无条件查询逻辑传播:

q.Strict().Term(p=>p.Name, userInput.Name);
&& q.Term("followers.firstName", userInput.FirstName)
&& q.Filtered(fq => fq
    .Query(qff => 
        qff.Terms(p => p.Country, userInput.Countries)
        && qff.Terms(p => p.Loc, userInput.Loc)
    )
)
Run Code Online (Sandbox Code Playgroud)

如果userInput.Countries和userInput.Loc都为null或为空,则不会发出整个筛选的查询.