需要知道如何使用数组中的c#搜索在ES中进行搜索

mar*_*olp 14 c# arrays elasticsearch

您好我是新手ElasticSearch,需要帮助.我正在使用c#(我以为我可以QueryRaw在字符串中使用一个我认为......).场景下方:

数据

{
    "id": "1",
    "title": "Small cars",
    "tagsColours": ["grey",
    "black",
    "white"],
    "tagsCars": ["Suzuki",
    "Ford"],
    "tagsKeywords": []
},
{
    "id": "2",
    "title": "Medium cars",
    "tagsColours": [],
    "tagsCars": ["VW",
    "Audi",
    "Peugeot"],
    "tagsKeywords": ["Sedan"]
},
{
    "id": "3",
    "title": "Big cars",
    "tagsColours": ["red",
    "black"],
    "tagsCars": ["Jeep",
    "Dodge"],
    "tagsKeywords": ["Van",
    "Big"]
}
Run Code Online (Sandbox Code Playgroud)

目的

我想根据用户的选择在代码列上应用过滤器.这些值将填充在带有选定值的tagsXXX数组列中.

  • 如果参数数组值不为空,则结果应至少包含一个实例.每个参数数组都相同.参数具有的值越多,应该进行更具体的搜索
  • 如果至少有一个值来自参数,该值与任何文档的标记列数组中的所有值匹配,则获取该文档.但如果另一个tagsXXX阵列上有另一个值,那么它应该考虑到它.
  • 如果标记参数数组没有值,则忽略该过滤器

期望的回应

A)如果用户只选择1个标签颜色(即=黑色),格式如下:

{
    id: "",
    title: "",
    tagsColours: ["black"],
    tagsCars: [],
    tagsKeywords: []
}
Run Code Online (Sandbox Code Playgroud)

我想获取Id = 2和id = 3的文档,因为它们的tagsColours中有黑色,而忽略tagsCars和tagsKeywords,因为参数没有值

B)如果用户只选择2个差异标签(即= color = black和cars = audi,以及mercedez benz),格式如下:

{
    id: "",
    title: "",
    tagsColours: ["black",
    "yellow"],
    tagsCars: ["Audi",
    "Mercedes Benz"],
    tagsKeywords: []
}
Run Code Online (Sandbox Code Playgroud)

我想得到id = 2的文件,因为它在tagsColours上发现黑色,它在tagsCars中发现了奥迪,它不应该拉文档id = 1,因为即使黑色在tagsColours上,也没有参数值(audi,mercedez benz) )是在其tagsCars值上

大家好,我在尝试搜索ElasticSearch时遇到问题,并在数组中查找值,并且参数没有值时.如果有人能帮助我,我会很高兴.我这样做了:

termsQuery = Query<StructuredData>.Terms(t => t.Field(f =>f.TagsColours).Terms(dataToSearch.TagsColours));
termsQuery = termsQuery && Query<StructuredData>.Terms(t => t.Field(f =>f.TagsCars).Terms(dataToSearch.TagsCars));
Run Code Online (Sandbox Code Playgroud)

我停在这里(没有添加第三个过滤器),因为我无法将两个过滤器混合在一起dataToSearch具有参数的值(相同的结构对象,原因.Search让我在这里做.搜索()

var settings = new ConnectionSettings(node);

var response = new ElasticClient(settings)
.Search<StructuredData>(
s => s.AllIndices()
.AllTypes()
.From(0)
.Size(50)
.Query(_ => termsQuery)
);
Run Code Online (Sandbox Code Playgroud)

但是当我使用超过1个过滤器时我遇到了问题..任何想法?是".Terms"正确的财产?

Fil*_*das 4

如果您在 ES 5 上使用常规映射 > 这将为您提供您想要的结果。如果没有,您将需要更改映射。

 QueryContainer query = null;

            if(dataToSearch.TagsColours != null && dataToSearch.TagsCars.Length > 0)
            {
                query = Query<StructuredData>.Terms(t=>t.Field("tagsColours.keyword").Terms(dataToSearch.TagsColours));
            }

            if(dataToSearch.TagsColours != null && dataToSearch.TagsCars.Length > 0)
            {
                var q =  Query<StructuredData>.Terms(t=>t.Field("tagsCars.keyword").Terms(dataToSearch.TagsCars));
                query = query == null ? q : query && q; 
            }

            if(dataToSearch.TagsKeywords != null && dataToSearch.TagsKeywords.Length > 0)
            {
                var q =  Query<StructuredData>.Terms(t=>t.Field("tagsKeywords.keyword").Terms(dataToSearch.TagsKeywords));
                query = query == null ? q : query && q; 
            }
Run Code Online (Sandbox Code Playgroud)

您遇到的问题是术语查询是在未分析的值上完成的,并且默认文本字段使用标准分析器。从 5 开始,他们添加了使用关键字分析器的关键字子字段,它本质上只是按原样放置术语,您可以按原始值进行搜索。标准分析器对单词进行标记化并将所有术语小写,因此无法找到 Audi,因为该术语是 audi。如果您只想小写输入字符串,这将无法解决 Mercedes Benz 问题,因为在标准术语中,这将变成 Mercedes a Benz 术语,两个术语而不是一个,换句话说,如果您输入 Mercedes 或 Benz 但不输入 Mercedes,则术语将返回结果奔驰。如果您想使用匹配查询进行不区分大小写的搜索,则需要添加自定义分析器。