我有以下工作并返回结果的RavenDB MultiMap索引。现在当我想要使用查询并尝试过滤数据时,我会得到以下消息:
The field 'Stock_Key' is not indexed, cannot query/sort on fields that are not indexed.
我正在尝试获取所有在特定仓库有库存的产品。_request.Warehouses
是可提供给查询的仓库ID列表。产品库存保存在数据库中的单独集合中,该集合保存相同SKU。
var query = await _session
.Query<Products_SearchUniqueBySku.Result, Products_SearchUniqueBySku>()
.Where(x => x.Stock.Any(y => y.Key.In(_request.Warehouses) && y.Value > 0))
.ToListAsync();
我一整天都在尝试索引密钥,但没有成功。希望能得到一些帮助。我还尝试通过RavenDB工作室中的一些RQL变体进行查询,但在那里得到了更多相同的消息。不确定RQL查询是否编写正确。
from index 'Products/SearchUniqueBySku'
where Stock.589e90c9-09bb-4a04-94fb-cf92bde88f97 > 0
The field 'Stock.589e90c9-09bb-4a04-94fb-cf92bde88f97' is not indexed, cannot query/sort on fields that are not indexed
from index 'Products/SearchUniqueBySku'
where Stock_589e90c9-09bb-4a04-94fb-cf92bde88f97 > 0
The field 'Stock_589e90c9-09bb-4a04-94fb-cf92bde88f97' is not indexed, cannot query/sort on fields that are not indexed
我使用的索引:
using System;
using System.Collections.Generic;
using System.Linq;
using Raven.Client.Documents.Indexes;
using MyProject.Models.Ordering.Entities;
using MyProject.Models.Ordering.Enums;
namespace MyProject.Ordering.Indexes;
public class Products_SearchUniqueBySku : AbstractMultiMapIndexCreationTask<Products_SearchUniqueBySku.Result>
{
public class Result
{
public string Sku { get; set; }
public ProductTypes Type { get; set; }
public string Name { get; set; }
public IDictionary<string, decimal> Stock { get; set; }
}
public Products_SearchUniqueBySku()
{
AddMap<Product>(
products => from product in products
where product.Type == ProductTypes.Simple
where product.Variants.Count == 0
select new
{
product.Sku,
product.Type,
product.Name,
Stock = new Dictionary<string, decimal>()
}
);
AddMap<Product>(
products => from product in products
where product.Type == ProductTypes.Simple
where product.Variants.Count > 0
from variant in product.Variants
select new
{
variant.Sku,
Type = ProductTypes.Variant,
Name = $"{product.Name} ({string.Join("/", variant.Mappings.Select(y => y.Value.Name))})",
Stock = new Dictionary<string, decimal>()
});
AddMap<StockItem>(
items => from item in items
group item by item.Sku
into grouped
select new
{
Sku = grouped.Key,
Type = ProductTypes.Variant,
Name = (string) null,
Stock = grouped.ToDictionary(x => x.Warehouse.Id, x => x.Stock)
}
);
Reduce = results => from result in results
group result by result.Sku
into grouped
let product = grouped.Single(x => x.Stock.Count == 0)
select new
{
Sku = grouped.Key,
product.Type,
product.Name,
Stock = grouped.SelectMany(x => x.Stock).ToDictionary(x => x.Key, x => x.Value),
};
}
}
在使用RavenDB Studio时得到的结果(只显示了部分,你可以明白):
from index 'Products/SearchUniqueBySku'
{
"Sku": "VANS-SH-38",
"Type": "Variant",
"Name": "Vans Men's Suede (Maat 38)",
"Stock": {
"589e90c9-09bb-4a04-94fb-cf92bde88f97": 10,
"98304a84-0f44-49ce-8438-8a959ca29b9d": 11
},
"@metadata": {
"@change-vector": null,
"@index-score": 1
}
},
{
"Sku": "889376",
"Type": "Simple",
"Name": "Apple Magic Trackpad (2021)",
"Stock": {
"589e90c9-09bb-4a04-94fb-cf92bde88f97": 15
},
"@metadata": {
"@change-vector": null,
"@index-score": 1
}
}
模型(为了简洁省略大部分属性):
public class StockItem
{
public EntityReference Warehouse { get; set; }
public string Sku { get; set; }
public decimal Stock { get; set; }
}
public class EntityReference
{
public string Id { get; set; }
public string Name { get; set; }
}
public class Product
{
public string Id { get; set; }
public string Name { get; set; }
public ProductTypes Type { get; set; }
public List<ProductVariant> Variants { get; set; }
}
public class ProductVariant
{
public string Sku { get; set; }
}
编辑:
基于 @Ayende Rahien 的回答,我不得不将 Reduce
更改为以下内容:
Reduce = results => from result in results
group result by result.Sku
into grouped
let product = grouped.Single(x => x.Stock.Count == 0)
let stock = grouped.SelectMany(x => x.Stock).ToDictionary(x => x.Key, x => x.Value)
select new
{
product.Id,
....
Stock = stock,
_ = stock.Select(x => CreateField("Stock_" + x.Key, x.Value)) <--
};
请参见索引的动态字段(文档)。然后我收到了以下信息:
Map and Reduce functions of a index must return identical types.
我通过在每个
AddMap
函数中添加_ = (string)null
属性(不确定是否是完美的解决方案,但它有效)来解决此问题,然后以下查询就可以工作:from index 'Products/SearchUniqueBySku'
where Stock_589e90c9-09bb-4a04-94fb-cf92bde88f97 > 0
StockItem
的AddMap
函数中放置了_
,而不是在Reduce
中。 - Tom Aalbers