简体   繁体   English

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

[英]NEST C# - elasticsearch - ecommerce filter combination

I am trying to implement elasticsearch into my webshop but having some troubles on using filters. 我正在尝试将弹性搜索应用到我的网上商店,但在使用过滤器方面遇到了一些麻烦。 The filtering is done dynamically. 过滤是动态完成的。

Example: 例:

I start with showing all the products that are indexed. 我首先展示了所有被索引的产品。 So no filter is applied. 所以没有应用过滤器。 Visitors can choose their own filters like: color, size, brand, type, category, .... 访客可以选择自己的过滤器,如:颜色,尺寸,品牌,类型,类别,....

But I don't now how to build the search result with elasticsearch and NEST. 但我现在不知道如何使用elasticsearch和NEST构建搜索结果。

This is my solution without filtering: 这是我没有过滤的解决方案:

var query = ElasticClient.Search<Product>(s => s
            .From(from)
            .Size(size)
        );

I also have another question on indexing a collection<> or list<>. 我还有另一个关于索引集合<>或列表<>的问题。 I had to use JsonIgnore on those collections. 我不得不在这些集合上使用JsonIgnore。 Could I index those as well? 我可以索引那些吗?

This is my class: 这是我的班级:

/// <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; }
    }


}

Is there someone who can help me? 有人可以帮助我吗?

Be sure to read the whole documentation on writing queries here: http://nest.azurewebsites.net/nest/writing-queries.html 请务必阅读有关编写查询的完整文档: http//nest.azurewebsites.net/nest/writing-queries.html

What follows is a pasted excerpt from there. 接下来是从那里粘贴的摘录。

Conditionless queries 无条件查询

Writing complex boolean queries is one thing but more often then not you'll want to make decisions on how to query based on user input. 编写复杂的布尔查询是一回事,但更常见的是,您不希望根据用户输入来决定如何进行查询。

public class UserInput
{
    public string Name { get; set; }
    public string FirstName { get; set; }
    public int? LOC { get; set; }
}

and then 接着

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

This again turns tedious and verbose rather quickly too. 这又一次变得乏味和冗长。 Therefor nest allows you to write the previous query as: 因此,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))
)

If any of the queries would result in an empty query they won't be sent to elasticsearch. 如果任何查询导致空查询,则不会将其发送到elasticsearch。

So if all the terms are null (or empty string) on userInput except userInput.Loc it wouldn't even wrap the range query in a boolean query but just issue a plain range query. 因此,如果userInput上的所有术语都为null(或空字符串),除了userInput.Loc,它甚至不会将范围查询包装在布尔查询中,而只是发出一个普通范围查询。

If all of them empty it will result in a match_all query. 如果所有这些都为空,则会产生match_all查询。

This conditionless behavior is turned on by default but can be turned of like so: 默认情况下会启用此无条件行为,但可以像这样调整:

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

However queries themselves can opt back in or out. 但是查询本身可以选择重新进入或退出。

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

In this example if userInput.Name is null or empty it will result in a DslException. 在此示例中,如果userInput.Name为null或为空,则将导致DslException。 The range query will use conditionless logic no matter if the SearchDescriptor uses .Strict() or not. 无论SearchDescriptor是否使用.Strict(),范围查询都将使用无条件逻辑。

Also good to note is that conditionless query logic propagates: 另外值得注意的是无条件查询逻辑传播:

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

If both userInput.Countries and userInput.Loc are null or empty the entire filtered query will be not be issued. 如果userInput.Countries和userInput.Loc都为null或为空,则不会发出整个筛选的查询。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM