繁体   English   中英

使用bodybuilder.js将点表示法JSON转换为弹性搜索深度嵌套的查询JSON?

[英]Convert dot-notation JSON into elastic search deeply nested query JSON, with bodybuilder.js?

如果我有一个平面数据结构,该结构使用点表示法表示深度。 看起来像这样:

 { 
   "key1": "name1",
   "key2.subKey.finalKey": "name2"
 }

我正在使用它来创建查询:

let query = _.reduce(jsonQuery, (queryBody, queryValue, queryName)=>{
    return queryBody.query("term", "queryName", "queryValue")
}, bodybuilder())

我已经简化了,但这绝不能处理伪嵌套数据。

我有一个可以将点符号转换为嵌套的函数。

这是健美运动员建议做嵌套结构的方法:

bodybuilder()
  .query('nested', 'path', 'obj1', (q) => {
    return q.query('match', 'obj1.color', 'blue')
  })
  .build()

这将导致以下查询结构:

{
  "query": {
    "nested": {
      "path": "obj1",
      "query": {
        "match": {
          "obj1.color": "blue"
        }
      }
    }
  }
}

因此,在我的多嵌套版本中,我希望获得:

{
  "query": {
    "nested": {
      "path": "key2",
      "query": {
        "nested": {
          "field": "key2.subkey",
          "query": {
            "match": {
              "key2.subkey.finalKey": "name2"
            }
          }
        }
      }
    }
  }
}

我正在努力思考如何根据上述伪嵌套结构动态地执行此操作。 递归的东西,但我不确定如何实现粗箭头功能。

这是到目前为止我得到的最接近的东西:

 const nestQuery = (chain, value, method="match") =>{ return q => q.query(method, chain, value) } const pathMapping = 'key2.subkey.finalKey'; const fooMapping = pathMapping.split('.').map((part, index, splitPath) =>{ return splitPath.slice(0, index+1).join('.'); }) const body = bodybuilder(); fooMapping.reduce((nestedBody, subPath, index, allPaths)=>{ const next = allPaths[index+1] return nestedBody.query('nested', subPath, nestQuery(next, 'blue')) }, body) console.log(body.build()) 
 <script src="https://rawgit.com/danpaz/bodybuilder/master/browser/bodybuilder.min.js"></script> 

但是,当我需要一个嵌套查询时,这为您提供了三个单独的查询。

您使用reduce直觉确实朝着正确的方向发展。 但是,如果您从最里面的查询(其参数与其他query调用看起来完全不同)开始朝相反的方向进行缩减,则将容易得多,并且可以反向进行。 这样,您就可以从内到外将以前构建的回调包装到另一个回调函数中:

 function buildQuery(path, value) { // Build one part less, as the last one needs a different query syntax anyway // ... and we have its value already in `path`: const keys = path.split('.').slice(0, -1).map((part, index, splitPath) => { return splitPath.slice(0, index+1).join('.'); }); // Use reduceRight to build the query from the inside out. const f = keys.reduceRight( (f, key) => { return q => q.query("nested", "path", key, f); // f is result of previous iteration }, q => q.query("match", path, value)); // Initial value is the innermost query return f(bodybuilder()).build(); } // Demo console.log(buildQuery("key2.subkey.finalKey", "name2")); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 
 <script src="https://rawgit.com/danpaz/bodybuilder/master/browser/bodybuilder.min.js"></script> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM