当前位置: 首页 > 知识库问答 >
问题:

弹性搜索的搜索查询

戚良弼
2023-03-14

我有以下格式的弹性搜索文档

{
   "stringindex" : {
   "mappings" : {
  "files" : {
    "properties" : {
      "BaseOfCode" : {
        "type" : "long"
      },
      "BaseOfData" : {
        "type" : "long"
      },
      "Characteristics" : {
        "type" : "long"
      },
      "FileType" : {
        "type" : "long"
      },
      "Id" : {
        "type" : "string"
      },
      "Strings" : {
        "properties" : {
          "FileOffset" : {
            "type" : "long"
          },
          "RO_BaseOfCode" : {
            "type" : "long"
          },
          "SectionName" : {
            "type" : "string"
          },
          "SectionOffset" : {
            "type" : "long"
          },
          "String" : {
            "type" : "string"
          }
        }
      },
      "SubSystem" : {
        "type" : "long"
      }
    }
  }
}

} }

我的要求是,当我搜索特定字符串(string.string)时,我只想获得该字符串的FileOffSet(string.FileOffSet)。我该怎么做?

谢谢

共有2个答案

林弘文
2023-03-14

丹的回答很好,但我认为他没有全部提及。

他的解决方案不适合你的问题,但我想你甚至不知道。

考虑一个场景,其中数据如下:,

文件1

{
  "Id": 1,
  "Strings": [
    {
      "string": "x",
      "fileoffset": "f1"
    },
    {
      "string": "y",
      "fileoffset": "f2"
    }
  ]
}

doc_2

{
  "Id": 2,
  "Strings": {
    "string": "z",
    "fileoffset": "f3"
  }
}

当你像丹说的那样运行时,比如让我们用Strings.string=x应用过滤器,然后响应就像,

{
  "hits": [
    {
      "_index": "stringindex",
      "_type": "files",
      "_id": "11961",
      "_score": 1,
      "_source": {
        "Strings": [
          {
            "fileoffset": "f1"
          },
          {
            "fileoffset": "f2"
          }
        ]
      }
    }
  ]
}

这是因为,elasticsearch将从嵌套字段(这里是字符串)中的任何对象通过过滤条件的文档中获得命中。(在这种情况下,在doc_1中,Strings.string=x通过了过滤器,因此返回doc_1。但是我们不知道哪个嵌套对象通过了标准。

因此,您必须使用nested_聚合,

这里有一个解决方案。。

POST index/type/_search
{
    "size": 0, 
   "aggs": {
      "StringsNested": {
         "nested": {
            "path": "Strings"
         },
         "aggs": {
            "StringFilter": {
               "filter": {
                  "term": {
                     "Strings.string": "x"
                  }
               },
               "aggs": {
                  "FileOffsets": {
                     "terms": {
                        "field": "Strings.fileoffset"
                     }
                  }
               }
            }
         }
      }
   }
}

所以,反应就像,

"aggregations": {
      "StringsNested": {
         "doc_count": 2,
         "StringFilter": {
            "doc_count": 1,
            "FileOffsets": {
               "buckets": [
                  {
                     "key": "f1",
                     "doc_count": 1
                  }
               ]
            }
         }
      }
   }

请记住将字符串映射为嵌套的,正如dan所说。

程志新
2023-03-14

我假设您想执行嵌套查询并仅检索一个字段作为结果,但我在您的映射中看到了问题,因此我将我的答案分为3部分:

  1. 我看到的问题是什么:
  2. 如何查询嵌套字段(这是更多的ES背景):
  3. 如何找到解决方案:

1) 我看到的问题是什么:

您想查询嵌套字段,但没有嵌套字段。

嵌套字段部分:

字段“Strings”未嵌套在“file”类型中(没有嵌套字段的嵌套数据可能会带来未来的问题),否则您对字段“Strings”的映射将如下所示:

{
  "stringindex" : {
    "mappings" : {
      "files" : {
        "properties" : {
          "Strings" : {
            "properties" : {
              "type" : "nested",
              "String" : {
                "type" : "string"
              }
            }
          }
        }
      }
    }
  }
}

注意:是的,我剪切了大部分字段,但我这样做是为了轻松显示您没有创建嵌套字段。

有了嵌套字段“在手”,我们需要一个嵌套查询。

具体字段结果部分:

要只检索一个字段作为结果,您必须在查询中包含属性“\u source”。

2) 如何查询嵌套字段:

如果您从未使用过嵌套字段,则这更适用于ES背景。

小示例:

使用嵌套字段定义类型:

{
  "nesttype" : {
        "properties" : {
            "name" :     { "type" : "string" },
            "parents" : {
                "type" : "nested" ,
                "properties" : {
                    "sex"       : { "type" : "string" },
                    "name"      : { "type" : "string" }
                }
            }
        }
    }
}

您创建一些输入:

{ "name" : "Dan", "parents" : [{ "name" : "John" , "sex" : "m" }, 
                               { "name" : "Anna" , "sex" : "f" }] }

{ "name" : "Lana", "parents" : [{ "name" : "Maria" , "sex" : "f" }] }

然后查询,但只获取嵌套字段“parents.name”:

{
  "query": {
    "nested": {
      "path": "parents",
      "query": {
        "bool": {
          "must": [
            {
              "term": {
                "sex": "m"
              }
            }
          ]
        }
      }
    }
  },
  "_source" : [ "parents.name" ]
}

这个查询的输出是“所有有‘m’性别父母的人的父母的名字”。一个条目(丹)有父亲,而另一个条目(拉娜)没有。所以它只能检索丹父母的名字。

3) 如何找到解决方案:

要修复您的映射:

您只需要在字段“Strings”中包含类型“nested”:

{
  "files" : {
        "properties" : {
            ...
            "Strings" : {
                "type" : "nested" ,
                "properties" : {
                    "FileOffset"    : { "type" : "long" },
                    "RO_BaseOfCode" : { "type" : "long" },
                    ...
                }
            }
            ...
        }
    }
}

查询数据:

{
  "query": {
    "nested": {
      "path": "Strings",
      "query": {
        "bool": {
          "must": [
            {
              "term": {
                "String": "my string"
              }
            }
          ]
        }
      }
    }
  },
  "_source" : [ "Strings.FileOffSet" ]
}
 类似资料:
  • 我正在LDAP服务器上工作。它有弹性搜索。我必须用一些Javascript代码(JSON格式)发送查询。 这是我的查询: 我试图打印所有结果,其中“server”=“server\u name”(该字段是server:server\u name…)。我认为关于弹性搜索的文档太小了。我找到了一些文档,但都是一样的,对新用户没有帮助。这个例子太简单了。 此查询返回所有结果,包括任何筛选器。 Ps:这就

  • 我使用Elasticsearch允许用户输入要搜索的术语。例如,我要搜索以下属性'name': 如果使用以下代码搜索或,我希望返回此文档。 我尝试过做一个bool must和做多个术语,但它似乎只有在整个字符串都匹配的情况下才起作用。 所以我真正想做的是,这个词是否以任何顺序包含两个词。 有人能帮我走上正轨吗?我已经在这上面砸了一段时间了。

  • 如何获得空数组和美国的结果和

  • 我刚加入弹性搜索公司。而不知道如何在JSON请求中对索引和an类型发出正确的请求?(所以我不想像localhost:9200/myindex/mytype/_search那样在URL中使用索引和类型,而是向localhost:9200/_search发出JSON请求) 我试过这样的东西。但我得到的结果是'AAA'索引而不是'BBB'索引。如何只从bbb索引得到结果或者根本没有结果?

  • 我有大量相同类型的实体,每个实体都有大量属性,并且我只有以下两种选择来存储它们: 将每个项存储在索引中并执行多索引搜索 将所有enties存储在单个索引中,并且只搜索1个索引。 一般而言,我想要一个时间复杂度之间的比较搜索“N”实体与“M”特征在上述每一种情况!

  • 我在术语查询中要求弹性搜索中的嵌套字段,其中嵌套字段值应与术语查询中提供的值的数量完全匹配。例如,考虑下面的查询,在这里我们对名为类型的嵌套字段进行查询。 GET资产/_search 索引映射 样本文件: 上述查询应返回字段类型正好有2个值的文档,即“VOD”