当前位置: 首页 > 面试题库 >

在elasticsearch.net中按字符串数组查询字符串数组

谭泉
2023-03-14
问题内容

我在C#中使用elasticsearch.net库,并尝试查询与指定过滤器匹配的对象。

我希望查询返回对象,其中对象的Names集合中至少存在来自过滤器的输入名称之一。

问题是此查询的结果总是使我命中0次,即使我确定数据库中确实存在与指定过滤器匹配的数据,我也想找出我的查询出了什么问题…

该模型:

public class A
{
    public int AId { get; set; }
    public IEnumerable<string> Names { get; set; }
}

过滤对象:

public class Filter
{
    public IEnumerable<string> NamesToSearch { get; set; }
}

查询数据的方法:

public async Task<IEnumerable<A>> GetFilteredData(Filter filter)
{
    var query = await _elasticClient.SearchAsync<A>(x => x.Query(q => q.Terms(a => a.Names, filter.NamesToSearch))
                                                            .Fields(a => a.AId, a => a.Names));

    return query.Hits
                .Select(x => new A
                                {
                                    AId = x.Fields.FieldValues<A, int>(a => a.AId)[0]
                                })
                .ToList();
}

我也尝试过以下查询,但都没有产生预期的结果:

var query = await _elasticClient.SearchAsync<A>(x => x.Query(q => q.Nested(n => n.Filter(f => f.Terms(y => y.Names, filter.NamesToSearch))))
                                                              .Fields(a => a.AId, a => a.Names));

适用于我的解决方案:

以使用ElasticSearch.net1.7.1进行实际编译,并且是类型安全的(没有按字符串引用字段名称),最后得到了以下扩展方法,对于我的场景而言,这就像一个魅力:

public static QueryContainer MatchAnyTerm<T>(this QueryDescriptor<T> descriptor, Expression<Func<T, object>> field, object[] values) where T : class, new()
{
    var queryContainer = new QueryContainer();

    foreach (var value in values)
    {
        queryContainer |= descriptor.Term(t => t.OnField(field).Value(value));
    }

    return queryContainer;
}

和用法:

var query = await _elasticClient.SearchAsync<A>(x => x.Query(q =>
                                                                q.Bool(b =>
                                                                    b.Should(s => s.MatchAnyTerm(a => a.Names, filter.NamesToSearch.ToArray()))
                                                                        .Fields(a => a.AId, a => a.Names));

问题答案:

我认为您的问题是您尝试将整个数组传递给查询。相反,您应该将其视为OR表达式。

以下是您应使用的原始查询:

{
    "query": {
        "bool": {
            "should": [
                { "term": {"names": "test" } },
                { "term": {"names": "xyz" } }
            ]
        }
    }
}

并通过C#代码实现这一目标。首先,我定义了辅助函数

private static QueryContainer TermAny<T>(QueryContainerDescriptor<T> descriptor, Field field, object[] values) where T : class
{
    QueryContainer q = new QueryContainer();
    foreach (var value in values)
    {
        q |= descriptor.Term(t => t.Field(field).Value(value));
    }
    return q;
}

现在查询:

string[] values = new[] { "test", "xyz" };
client.Search<A>(x => x.Query(
    q => q.Bool(
        b => b.Should(s => TermAny(s, "names", values)))));


 类似资料:
  • 问题是,我试图这么做,但我检查字符串长度的方法不起作用;我能做些什么来修复它?

  • 问题内容: 是否存在通过查询字符串传递数组的标准方法? 需要明确的是,我有一个带有多个值的查询字符串,其中一个是数组值。我希望将该查询字符串值视为一个数组-我不希望该数组爆炸,以使其与其他查询字符串变量没有区别。 编辑: 根据@Alex的答案,没有标准的方法可以执行此操作,因此我的后续工作是什么才是 识别 我正在读取的参数同时是 PHP 和 Javascript 数组的简单方法? 用相同的名称命名

  • 我有一个数组: 如何根据数组中每个元素中包含的数字对数组进行排序?

  • 我的一个朋友问我关于他们的讲师作为练习给他们的一个编码挑战。我找到了一个解决办法。但我认为,对于一个简单的分类问题来说,这个解决方案太长了。所以,我想问一下,是否有更直接的方法来解决这个挑战。 具有函数third_greatest(),它接受一个字符串数组并返回第三大单词。因此,例如:如果数组是[“你好”、“世界”、“之前”、“中午”],则输出应该是“世界”,因为“之前”是六个字母长,“你好”和“

  • 我试图获取任意长度的字符串[],并将其打印成字符串,最好使用字段分隔符。现在我有: 但是由于某种原因,它只是返回“第二个”值。我如何使它正确连接这些值? 另外,我可以使用来简化代码吗?谢谢

  • 问题内容: 如何将下面的 字符串 转换为 数组 ? 这是我要寻找的阵列, 问题答案: 您需要该函数,并且需要设置第二个参数以将数据放入数组中,而不是放入单个变量中。