搜索弹性搜索查询

时间:2014-08-08 12:02:47

标签: elasticsearch

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

{
   "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 个答案:

答案 0 :(得分:2)

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

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

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

    嵌套字段部分:

    The field" Strings"不嵌套在类型"文件" (没有嵌套字段的嵌套数据可能会带来未来的问题),否则你的字段映射"字符串"会是这样的:

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

    注意:是的,我剪切了大部分字段,但我这样做很容易表明你没有创建嵌套字段。

    使用嵌套字段"在手中#34;,我们需要一个嵌套查询。

    特定字段结果部分:

    要仅检索一个字段作为结果,您必须包含属性" _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' &#34 ;.一个条目(丹)有一个父亲,而另一个(拉娜)没有。所以它只会找回丹的父母名字。

    3)如何找到解决方案:

    修复映射:

    您只需要包含类型"嵌套"在现场" Strings":

    {
      "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" ]
    }
    

答案 1 :(得分:0)

dan 给出了很好的答案,但我认为他没有提到这一切。

他的解决方案对你的问题不起作用,但我想你甚至都不知道。

考虑一个数据类似的场景,

<强> doc_1

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

<强> doc_2

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

当你运行类似 dan 时,就像说让我们使用Strings.string = x应用过滤器然后响应就好了,

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

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

所以,你必须使用nested_aggregation

这是一个适合您的解决方案..

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 表示。