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

匹配完整的复杂嵌套集合项,而不是通过Elastic Search匹配单独的成员

裴心水
2023-03-14
问题内容

我有一个索引,其中包含我要命中的项目的嵌套集合。集合项包含多个必须全部与某个查询匹配的属性,而不仅仅是其中的任何一个。这是模型:

public class IndexEntry1
{
    public IEnumerable<NestedType1> NestedProperty1 { get; set; }
}

public class NestedType1
{
    public string Member1 { get; set; }
    public string Member2 { get; set; }
}

因此,我只想点击集合中具有Member1Member2值特定组合的文档IndexEntry1.NestedProperty1

我认为必须将集合映射为嵌套。

这是映射:

index: {
    properties: {
        nestedProperty1: {
            type: "nested",
            properties: {
                member1: {
                    type: "string",
                    index_analyzer: "my_index_analyzer_1",
                    search_analyzer: "my_search_analyzer_1"
                },
                member2: {
                    type: "string",
                    analyzer: "keyword"
                }
            }
        }
    },
    analysis: {
        tokenizer: {
            my_ngram: {
                type: "nGram",
                min_gram: "1",
                max_gram: "15"
            }
        },
        analyzer: {
            my_index_analyzer_1: {
                type: "custom",
                tokenizer: "my_ngram",
                filters: ["lowercase"]
            },
            my_search_analyzer_1: {
                type: "custom",
                tokenizer: "whitespace",
                filters: ["lowercase"]
            }
        }
    }
}

并使用如下查询:

client.Search<IndexEntry1>(d => d
    .Query(query => query
        .Nested(n => n
            .Path(p => p.NestedProperty1)
                .Query(q => q
                    .Bool(b => b
                        .Must(
                            m => m.Term("member1", "value1"),
                            m => m.QueryString(s => s.OnField("member2")
                                .Query("value2"))))))));

但是,我仍然会遇到具有该value1值或该value2值的任何文档的命中,而我希望仅对具有相同值的两个值在同一NestedProperty1收集项目上的文档进行命中。


问题答案:

您是正确的,它只应查找嵌套文档具有value1和value2的文档。

您可以通过合理运行以下命令(chrome插件)来观察这是Elasticsearch的行为:

PUT http://localhost:9200/nested_example
{
    "mappings": {
        "indexentry" : {
            "properties": {
                "nestedCollection": {
                    "type": "nested",
                    "properties": {
                        "prop1" : { "type": "string", "index": "not_analyzed" },
                        "prop2" : { "type": "string", "index": "not_analyzed" }
                    }
                }
            } 
        }
    }
}
POST http://localhost:9200/nested_example/indexentry/1
{
    "nestedCollection": [
        { "prop1" : "A", "prop2" : "A" },
        { "prop1" : "B", "prop2" : "B" }
    ]
}
POST http://localhost:9200/nested_example/indexentry/2
{
    "nestedCollection": [
        { "prop1" : "C", "prop2" : "C" },
        { "prop1" : "D", "prop2" : "D" }
    ]
}

POST http://localhost:9200/nested_example/indexentry/_search
{
    "query": {
        "nested": {
           "path": "nestedCollection",
           "query": {
                "bool": {
                    "must": [
                       {
                           "term": {
                              "nestedCollection.prop1": {
                                 "value": "A"
                              }
                           }
                       },
                       {
                           "term": {
                              "nestedCollection.prop2": {
                                 "value": "A"
                              }
                           }
                       }

                    ]
                }
           }
        }
    }
}

先前的查询将仅找到文档,1但是一旦您更改术语查询nestedColleciton.prop2以查找B而不是A您,将不再获得预期的任何响应。

如果我更新该示例以使其更符合您的映射和查询,则无法重现您的见证行为:

PUT http://localhost:9200/nested_example
{
   "settings": {
      "analysis": {
         "tokenizer": {
            "my_ngram": {
               "type": "nGram",
               "min_gram": "1",
               "max_gram": "15"
            }
         },
         "analyzer": {
            "my_index_analyzer_1": {
               "type": "custom",
               "tokenizer": "my_ngram",
               "filters": [
                  "lowercase"
               ]
            },
            "my_search_analyzer_1": {
               "type": "custom",
               "tokenizer": "whitespace",
               "filters": [
                  "lowercase"
               ]
            }
         }
      }
   },
   "mappings": {
      "indexentry": {
         "properties": {
            "nestedCollection": {
               "type": "nested",
               "properties": {
                  "prop1": {
                     "type": "string",
                     "index_analyzer": "my_index_analyzer_1",
                     "search_analyzer": "my_search_analyzer_1"
                  },
                  "prop2": {
                     "type": "string",
                     "analyzer": "keyword"
                  }
               }
            }
         }
      }
   }
}
POST http://localhost:9200/nested_example/indexentry/1
{
    "nestedCollection": [
        { "prop1" : "value1", "prop2" : "value1" },
        { "prop1" : "value2", "prop2" : "value2" }
    ]
}
POST http://localhost:9200/nested_example/indexentry/2
{
    "nestedCollection": [
        { "prop1" : "value3", "prop2" : "value3" },
        { "prop1" : "value4", "prop2" : "value4" }
    ]
}

POST http://localhost:9200/nested_example/indexentry/_search
{
    "query": {
        "nested": {
           "path": "nestedCollection",
           "query": {
                "bool": {
                    "must": [
                       {
                           "term": {
                              "prop1": {
                                 "value": "value1"
                              }
                           }
                       },
                       {
                           "query_string": {
                               "fields": [
                                  "prop2"
                               ],
                               "query": "value1"

                           }
                       }

                    ]
                }
           }
        }
    }
}

您可以更新前面的示例以更好地重现您的情况吗?

在NEST中,您可以将查询重写为:

client.Search<IndexEntry1>(d => d
    .Query(query => query
        .Nested(n => n
            .Path(p => p.NestedProperty1)
            .Query(q => 
                q.Term(p => p.NestedProperty1.First().Member1, "value1")
                && q.QueryString(s => s
                    .OnField(p => p.NestedPropery1.First().Member2)
                    .Query("value2")
                )
            )
        )
    );

类型强,嵌套少。



 类似资料:
  • 目前我有这个阵列= 条件: 如果每个嵌套数组index2都相同,那么我想用[0.0 1.0,1.0 2.0,2.0 3.0,3.0 4.0] = [1.0,3.0,5.0,7.0]来求和 我想要的最终结果:[[“efg”, [1.0, 3.0, 5.0, 7.0], “测试”]] 有什么方法或建议来获得这个结果吗?

  • 问题内容: 我正在使用Elasticsearch,但有一段时间魔鬼般地要进行精确匹配。我已经尝试过match,query_string等的各种组合,但是我什么也没得到,或者得到了不好的结果。查询看起来像这样: 排序结果 我当然知道“狗”,“那只狗”和“狗”的得分相同,但是我需要弄清楚如何提高得分“狗”的精确匹配度。 我也试过 但这仍然给我 问题答案: 默认情况下,使用标准分析仪分析字段。如果您想检

  • 问题内容: 在以下示例中: 为什么对second(b)的调用有效,但对third(a)的调用却无效 ? 我收到以下错误: 问题答案: 如果您希望能够使用自变量进行调用,则需要将签名更改为此: 将上面的工作,因为不像,是兼容。这样想: 推理很简单。如果你有 然后,如果您 可以这样 调用该方法:

  • 该示例摘自Elasticsearch参考:https://www.elastic.co/guide/en/Elasticsearch/reference/5.3/nested.html 我的索引和这个差不多。唯一的区别是user.first和user.last是关键字类型,所以我可以对它们使用过滤器。 在两种情况下,我应该使用什么查询来获取与上面数组匹配的文档(正好是两个项,一个项是John Sm

  • 问题内容: 我在索引文档中具有以下结构: 我可以使用匹配查询“ customLists.id = 26”来搜索属于给定列表的匹配文档。但是我需要根据该列表中的位置值对文档进行排序,并忽略其他列表的位置。 因此,预期结果将按document2,document1,document3的顺序排列 数据结构是否适合这种排序以及如何处理? 问题答案: 实现此目的的一种方法是将的映射类型设置 为嵌套,然后使用

  • 问题内容: 我正在使用Elasticsearch的php库对我的网站进行索引和查找文档。这是用于创建索引的代码: 然后,我使用curl XPUT将文档添加到索引,并使用XGET查询索引。除了返回结果时跨索引的单数和复数查询词不匹配之外,这种方法效果很好。例如,当我搜索“讨论”时,不返回“讨论”的匹配项,反之亦然。为什么会这样呢?我认为这是默认情况下在Elasticsearch中处理的。为了匹配单数