Эластичный .Nest Эквивалент field_value_factor

Мне нужно пересмотреть метод, который строит SearchDescriptor с использованием .Nest, чтобы оценка результатов поиска продуктов была выше для товаров, имеющих договорную цену (нулевое значение).

Я захватил сериализованную версию запроса, добавив «field_value_factor», чтобы вернуть результаты в нужном порядке. Я не определил, как добиться этого в операторе запроса .Nest.

Может ли кто-нибудь порекомендовать, как пересмотреть операторы клиента .NEST, чтобы создать тот же дескриптор поиска?

Спасибо

Ниже приведен запрос, который мы хотим получить, где вы увидите field_value_factor внизу:

 {
      "from": 0,
  "size": 3000,
  "sort": [
    {
      "_score": {
        "order": "desc"
      }
    },
    {
      "priceStatus": {
        "order": "asc"
      }
    },
    {
      "unitPrice": {
        "order": "asc"
      }
    }
  ],
  "aggs": {
    "PriceStatus": {
      "terms": {
        "field": "priceStatus",
        "size": 5
      }
    },
    "VendorName": {
      "terms": {
        "field": "vendorName",
        "size": 5
      }
    },
    "CatalogName": {
      "terms": {
        "field": "catalogName",
        "size": 5
      }
    },
    "ManufacturerName": {
      "terms": {
        "field": "manufacturerName",
        "size": 5
      }
    },
    "IsGreen": {
      "terms": {
        "field": "isGreen",
        "size": 5
      }
    },
    "IsValuePack": {
      "terms": {
        "field": "isValuePack",
        "size": 5
      }
    },
    "UnitOfMeasure": {
      "terms": {
        "field": "unitOfMeasure",
        "size": 5
      }
    },
    "Attributes": {
      "nested": {
        "path": "attributes"
      },
      "aggs": {
        "TheAttributeName": {
          "terms": {
            "field": "attributes.name",
            "size": 10
          },
          "aggs": {
            "TheAttributeValue": {
              "terms": {
                "field": "attributes.value",
                "size": 5
              }
            }
          }
        }
      }
    }
  },
  "query": {
    "function_score": { 
       "query": {
        "bool": {
          "should": [
            {
              "multi_match": {
                "type": "phrase",
                "query": "pen",
                "slop": 3,
                "boost": 16.0,
                "fields": [
                  "itemNumber*^4",
                  "shortDescription*^4",
                  "subCategory1Name*^1.5",
                  "subCategory2Name*^2.0",
                  "categoryName*^0.9",
                  "longDescription*^0.6",
                  "catalogName*^0.30",
                  "manufactureName*^0.20",
                  "vendorName*^0.15",
                  "upcCode*^0.10"
                ]
              }
            },
            {
              "multi_match": {
                "query": "pen",
                "boost": 15.0,
                "minimum_should_match": "75%",
                "fields": [
                  "itemNumber*^4",
                  "shortDescription*^4",
                  "subCategory1Name*^1.5",
                  "subCategory2Name*^2.0",
                  "categoryName*^0.9",
                  "longDescription*^0.6",
                  "catalogName*^0.30",
                  "manufactureName*^0.20",
                  "vendorName*^0.15",
                  "upcCode*^0.10"
                ]
              }
            },
            {
              "multi_match": {
                "query": "pen",
                "fuzziness": 1.0,
                "slop": 2,
                "minimum_should_match": "75%",
                "fields": [
                  "itemNumber*^4",
                  "shortDescription*^4",
                  "subCategory1Name*^1.5",
                  "subCategory2Name*^2.0",
                  "categoryName*^0.9",
                  "longDescription*^0.6",
                  "catalogName*^0.30",
                  "manufactureName*^0.20",
                  "vendorName*^0.15",
                  "upcCode*^0.10"
                ]
              }
            }
          ]
        }
      },
      "filter": {
        "bool": {
          "must": [
            {
              "terms": {
                "catalogId": [
                  "fbb3dd2c-f81c-4ff3-bd5b-9c2cffc51540"
                ]
              }
            }
          ]
        }
      },
            "field_value_factor": {
                "field": "priceStatus",
                "factor": -1,
                "modifier": "none"
            }
        }
    }
}

Ниже приведен текущий метод, который создает SearchDescriptor:

private SearchDescriptor<SearchItem> BuildSearchDescriptor(
        string searchTerm,
        IList<Guid> catalogIds,
        int from,
        int size,
        string index,
        string preference,
        int attrSize,
        int valueSize,
        Dictionary<string, string[]> filterProps,
        Dictionary<string, string[]> filterAttrs,
        Guid? categoryId)
    {
        var searchDescriptor = new SearchDescriptor<SearchItem>()
            .From(from)
            .Size(size)
            .Query(q =>
                q.Filtered(fd => BuildFilterTerms(fd, filterProps, filterAttrs, catalogIds, categoryId)
                    .Query(iq => BuildQueryContainer(iq, searchTerm))
                )                    
            )
            .Index(index)
            .Preference(preference)
            .Aggregations(agg => BuildAggregationDescriptor(agg, attrSize, valueSize, catalogIds.Count))          
            .Sort(sort => sort.OnField("_score").Descending())
            .SortAscending(p=> p.PriceStatus)
            .SortAscending(p => p.UnitPrice);

        // Debug the raw string that will post to the ES servers i.e. use this in postman
        //var str = System.Text.Encoding.UTF8.GetString(client.Serializer.Serialize(searchDescriptor));

        return searchDescriptor;
    }

person ghoh    schedule 03.10.2017    source источник


Ответы (1)


Ваш запрос JSON недействителен; field_value_factor является функцией запроса function_score. В NEST 1.x это будет выглядеть так

var response = client.Search<Document>(x => x
    .Query(q => q
        .FunctionScore(fs => fs
            .Functions(fu => fu
                .FieldValueFactor(fvf => fvf
                    .Field(f => f.PriceStatus)
                    .Factor(-1)
                    .Modifier(FieldValueFactorModifier.None)
                )
            )
        )
    )
);

public class Document
{
    public string Title { get; set; }

    public int PriceStatus { get; set; }
}

который производит запрос

{
  "query": {
    "function_score": {
      "functions": [
        {
          "field_value_factor": {
            "field": "PriceStatus",
            "factor": -1.0,
            "modifier": "none"
          }
        }
      ]
    }
  }
}
person Russ Cam    schedule 05.10.2017