在布尔查询中应该多多必须

时间:2017-05-30 07:16:32

标签: elasticsearch nest elasticsearch-plugin elasticsearch-marvel

您好我在巢中使用以下查询

                Query<Person>
               .Bool(fd => fd
                   .Must(must => must
                   .Match(m => m
                     .Field("first_name")
                     .Query(p.first_name)
                     .Fuzziness(Fuzziness.EditDistance(2))),
                    must => must
                        .Match(ln => ln
                        .Field("last_name")
                         .Query(p.last_name)
                         .Fuzziness(Fuzziness.EditDistance(2))))

                         .Should(ffn => ffn
                       .Match(m => m
                         .Field("father_first_name")
                         .Query(p.father_first_name)
                         .Fuzziness(Fuzziness.EditDistance(2))))
                          .Should(fln => fln 
                           .Match(m => m
                             .Field("father_last_name")
                             .Query(p.father_last_name)
                             .Fuzziness(Fuzziness.EditDistance(2)))));

及以下是为同一个

生成的json查询
     {"query":{"bool":{"must":[{"match":{"first_name":
     {"query":"abigail","fuzziness":2}}},{"match":{"last_name":
     {"query":"may","fuzziness":2}}}],"should":[{"match":
     {"father_last_name":{"query":"s","fuzziness":2}}}]}}}

即使我为father_first_name传递1st should子句的值,它也仅为father_last_name采用last should子句。具有讽刺意味的是,如果我为father_last_name注释掉last should子句并保留1st should子句,则它开始采用father_first_name

  Modified nest query with only 1 should clause
  Query<Person>

               .Bool(fd => fd
                   .Must(must => must
                   .Match(m => m
                     .Field("first_name")
                     .Query(p.first_name)
                     .Fuzziness(Fuzziness.EditDistance(2))),
                    must => must
                        .Match(ln => ln
                        .Field("last_name")
                         .Query(p.last_name)
                         .Fuzziness(Fuzziness.EditDistance(2))))

                         .Should(ffn => ffn
                       .Match(m => m
                         .Field("father_first_name")
                         .Query(p.father_first_name)
                         .Fuzziness(Fuzziness.EditDistance(2)))));

将返回

     {"query":{"bool":{"must":[{"match":{"first_name":
     {"query":"abigail","fuzziness":2}}},{"match":{"last_name":
     {"query":"may","fuzziness":2}}}],"should":[{"match":
     {"father_first_name":{"query":"t","fuzziness":2}}}]}}}

如何向查询添加多个

               .Bool(fd => fd
                   .Must(must => must
                   .Match(m => m
                     .Field("first_name")
                     .Query(p.first_name)
                     .Fuzziness(Fuzziness.EditDistance(2))),
                    must => must
                        .Match(ln => ln
                        .Field("last_name")
                         .Query(p.last_name)
                         .Fuzziness(Fuzziness.EditDistance(2))))
                         .Should(should => should
                       .Match(m => m
                         .Field("father_first_name")
                         .Query(p.father_first_name)
                         .Fuzziness(Fuzziness.EditDistance(2))),
                         should => should.Match(m => m
                             .Field("father_last_name")
                             .Query(p.father_last_name)
                             .Fuzziness(Fuzziness.EditDistance(2)))),
                             should => should.Match(m => m
                                 .Field("mother_first_name")
                                 .Query(p.mother_first_name)
                                 .Fuzziness(Fuzziness.EditDistance(2)))))

1 个答案:

答案 0 :(得分:1)

您正在调用Should(..)两次,第二次调用会覆盖第一次调用的值。 Should需要params Func<QueryContainerDescriptor<T>, QueryContainer>[],因此调用应与Must()调用相似

client.Search<Person>(s => s
    .Query(q => q
        .Bool(fd => fd
            .Must(must => must
                .Match(m => m
                    .Field("first_name")
                    .Query("first name")
                    .Fuzziness(Fuzziness.EditDistance(2))
                ),
            must => must
                .Match(ln => ln
                    .Field("last_name")
                    .Query("last name")
                    .Fuzziness(Fuzziness.EditDistance(2))
                )
            )
            .Should(should => should
                .Match(m => m
                    .Field("father_first_name")
                    .Query("father first name")
                    .Fuzziness(Fuzziness.EditDistance(2))
                ),
                should => should
                    .Match(m => m
                        .Field("father_last_name")
                        .Query("father last name")
                        .Fuzziness(Fuzziness.EditDistance(2))
                    )
                )
            )
        )
    );

With operator overloading,这可以缩短为

client.Search<Person>(s => s
    .Query(q => q
        .Match(m => m
            .Field("first_name")
            .Query("first name")
            .Fuzziness(Fuzziness.EditDistance(2))
        ) && q
        .Match(ln => ln
            .Field("last_name")
            .Query("last name")
            .Fuzziness(Fuzziness.EditDistance(2))
        ) && (q
            .Match(m => m
                .Field("father_first_name")
                .Query("father first name")
                .Fuzziness(Fuzziness.EditDistance(2))
            ) || q
            .Match(m => m
                .Field("father_last_name")
                .Query("father last name")
                .Fuzziness(Fuzziness.EditDistance(2))
            ))
        )
    );