电子商务项目中的全球搜索:Elastic Nest

时间:2019-07-19 06:19:58

标签: elasticsearch nest

我有一个问题,我无法在每个字段的所有文档中搜索我的搜索关键字。我需要一种功能,其中搜索关键字将使用LIKE功能搜索每个字段。截至目前,我正在使用.Match和.Multi_Match进行搜索,但是它不能满足我的要求,因为如果用户输入多个单词,则它在每个字段中都匹配搜索键,并且找不到任何值。因此需要这里的支持。在较早的NEST中使用了_all函数,这很好,但是在NEST最新的框架中没有_all方法。请在这里帮助我们。如果需要我身边的任何信息。请告诉我。

我已经尝试过使用Match和Multi_Match以及MatchAll函数,但是没有任何事情可以满足我的要求。

enter code here
m => m.MultiMatch(lk =>
                                                                   {
                                                                       var query = new MultiMatchQueryDescriptor<CarSearchRequest>();
                                                                       if (searchAjaxRequest.query != null)
                                                                       {
                                                                           query = lk.Fields(f1 => f1.Fields(f2 => f2.model, f3 => f3.variant, f4 => f4.carType, f5 => f5.fuelType)).Query(searchAjaxRequest.query.ToLower());
                                                                           return query;
                                                                       }
                                                                       return query;
                                                                   }),

1 个答案:

答案 0 :(得分:0)

_all字段是deprecated in Elasticsearch 6.x,在Elasticsearch 7.x中已删除。 NEST客户反映了这一变化。

给出POCO

public class Employee
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Salary { get; set; }
    public DateTime Birthday { get; set; }
    public bool IsManager { get; set; }
    public List<Employee> Employees { get; set; }
    public TimeSpan Hours { get; set; }
}

您可以在7.x版中使用copy_to创建自己的_all- like 字段

var client = new ElasticClient();

var createIndexResponse = client.Indices.Create("employees", c => c
    .Map<Employee>(m => m
        .AutoMap()
        .Properties(p => p
            .Text(t => t
                .Name("my_all_field")
                // specify any other settings for my_all_field e.g. analyzer
            )
            // .... etc...
        )
    )   
);

例如,如果您要将所有string POCO属性复制到您的copy_to字段,则可以在这里利用visitor pattern for mapping。首先创建一个访客

public class CopyAllStringPropertiesVisitor : NoopPropertyVisitor
{
    public override void Visit(ITextProperty type, PropertyInfo propertyInfo, ElasticsearchPropertyAttributeBase attribute)
    {
        base.Visit(type, propertyInfo, attribute);      
        type.CopyTo = Infer.Fields("my_all_field");
    }
}

然后将其传递给AutoMap

var createIndexResponse = client.Indices.Create("employees", c => c
    .Map<Employee>(m => m
        .AutoMap(new CopyAllStringPropertiesVisitor())
        .Properties(p => p
            .Text(t => t
                .Name("my_all_field")
                // specify any other settings for my_all_field e.g. analyzer
            )
        )
    )
);

这将导致以下映射

{
  "mappings": {
    "properties": {
      "firstName": {
        "copy_to": ["my_all_field"],
        "fields": {
          "keyword": {
            "ignore_above": 256,
            "type": "keyword"
          }
        },
        "type": "text"
      },
      "lastName": {
        "copy_to": ["my_all_field"],
        "fields": {
          "keyword": {
            "ignore_above": 256,
            "type": "keyword"
          }
        },
        "type": "text"
      },
      "salary": {
        "type": "integer"
      },
      "birthday": {
        "type": "date"
      },
      "isManager": {
        "type": "boolean"
      },
      "employees": {
        "properties": {},
        "type": "object"
      },
      "hours": {
        "type": "long"
      },
      "my_all_field": {
        "type": "text"
      }
    }
  }
}

要在搜索时使用copy_to字段

var searchResponse = client.Search<Employee>(s => s
    .Query(q => q
        .Match(m => m
            .Field("my_all_field")
            .Query("some query input")
        )
    )
);