2017-08-09 93 views
2

我是elasticsearch的新手。我有两个文件是JarFileData和ClassData。我用jarFileId字段链接了这两个文档。在elasticsearch中查询

这是ClassData

{ 
"_id" : ObjectId("59881021e950041f0c6fa1fa"), 
"ClassName" : "Exception", 
"jarFileId" : "JAR-0001", 
"dependencies" : [ 
    { 
     "dependedntClass" : "java/lang/RuntimeException", 
     "methodSignature" : "<init>" 
    }, 
    { 
    { 
     "dependedntClass" : "java/awt/EventQueue", 
     "methodSignature" : "isDispatchThread" 
    }, 
    { 
     "dependedntClass" : "Exception", 
     "methodSignature" : "setStackTrace" 
    } 
] 
} 

这是JarFileData

{ 
"_id" : ObjectId("59881021e950041f0c6fa1f7"), 
"jarFileName" : "Client.jar", 
"jarFileId" : "JAR-0001", 
"directory" : "C:\\Projects\\Test\\Application", 
"version" : null, 
"artifactID" : null, 
"groupID" : null 
} 

我想给一个目录,并获得在该目录中的所有jarfiles中,并用它来寻找在ClassData类型的依赖类那些jar文件。

这是我在node.js中用于检索给定目录的jarFileData类型的函数。

const test = function test() { 
let body = { 
    size: 20, 
    from: 0, 
    { 
    query: { 
    match: { 
     directory: 'C:\\Projects\\Test\\Application' 
     } 
     } 
    } 
    }; 
} 

我想使用上述查询的结果集来查询classData类型。 我被困在这部分很长一段时间,不知道如何在弹性搜索中做到这一点。任何帮助将非常感激。

+0

你有什么尝试?也可能会注意到,这里的mongodb查询尝试实际上是从“shell”运行的。您的弹性搜索查询需要从您希望实施的实际语言环境运行。因此,它可以帮助您至少显示您正在尝试的内容,从而可以在您使用的实际环境中回答您的问题。哪个不会是mongodb shell。 –

+0

我想用node.js查询弹性搜索。我尝试过并且成功地进行了简单的查询,但是我无法完成我需要做的复杂查询。 –

+0

是的,我们可以阅读。你被要求提供的是“一些代码,显示你试图这样做”。没有这些,这成为*“为我写代码”*许多人会选择忽略的问题。显示一个“尝试”,人们通常很乐意帮助“更正/使用”等。 –

回答

1

之前,你可以走得更远,有需要完成两个步骤:

  • jarFileIddependedntClass字段应该被映射为keyword类型(如果这是你可以使用keyword类型的multi-field field问题,并在查询中使用它们)
  • dependencies应该nested object

这两者之间看你的数据,连接元件文件类型为jarFileId字段。如果您现有的查询为您提供了结果,例如罐子的这个名单:具有此信息

{[{"jarFileId": "JAR-0001"},{"jarFileId": "JAR-0002"}]} 

,您可以使用此查询:

{ 
    "size":0, 
    "query":{ 
     "constant_score":{ 
     "filter":{ 
      "terms":{ "jarFileId":["JAR-0001","JAR-0002"] } 
     } 
     } 
    }, 
    "aggs":{ 
     "filtered":{ 
     "filter":{ 
      "constant_score":{ 
       "filter":{ 
        "terms":{ "jarFileId":["JAR-0001","JAR-0002"] } 
       } 
      } 
     }, 
     "aggs":{ 
      "dependent":{ 
       "nested":{ 
        "path":"dependencies" 
       }, 
       "aggs":{ 
        "classes":{ 
        "terms":{ 
         "field":"dependencies.dependedntClass" 
        } 
        } 
       } 
      } 
     } 
     } 
    } 
} 

而作为一个结果,你会得到:

{ 
    ..., 
    "aggregations": { 
     "filtered": { 
      "doc_count": 1, 
      "dependent": { 
       "doc_count": 3, 
       "classes": { 
        "doc_count_error_upper_bound": 0, 
        "sum_other_doc_count": 0, 
        "buckets": [ 
         { 
          "key": "core/internal/TrackingEventQueue$TrackingException", 
          "doc_count": 1 
         }, 
         { 
          "key": "java/awt/EventQueue", 
          "doc_count": 1 
         }, 
         { 
          "key": "java/lang/RuntimeException", 
          "doc_count": 1 
         } 
        ] 
       } 
      } 
     } 
    } 
} 

以您目前的模式,不可能用一个查询来完成 - elsticsearch没有连接机制。单个文档应该具有所有必要的信息,以便elasticsearch能够确定它是否与查询匹配。这是很好地描述here。因此,如果搜索的性能是此处的核心问题,那么要么使用application-side joins(类似于您的链接下的示例)或denormalize your data。我知道的唯一内置的“连接机制”是Term Filter Lookup,但它只允许在id字段中操作。

+0

非常感谢,事情是我想要一种方法来使用第二个查询中第一个查询的结果集。我已经设法分开做,因为你已经完成了上述工作。但是我不能在第二个查询中使用第一个查询的结果集。再一次感谢你。 –

+0

@ M.Ramzan - 我更新了我的答案。 – Joanna

+0

这就是我所寻找的,我会尝试更新我的模型并做到这一点。非常感谢。 –