查询多对多关系:按名称

时间:2016-03-09 17:49:16

标签: javascript many-to-many relationship loopbackjs

这实际上应该很容易,但我没有管理....

假设我们有一个模型ProductProduct可以有多个Tag。这种关系定义如下:

common/models/product.json

{
  "name": "Product",
  #other stuff
  "relations": {
      "tags": {
      "type": "hasMany",
      "model": "Tag",
      "foreignKey": "productId",
      "through": "ProductTags"
    }
  },
  #more stuff
}

common/models/product-tags.json

{
  "name": "ProductTags",
  #more stuff
  "relations": {
    "product": {
      "type": "belongsTo",
      "model": "Product",
      "foreignKey": "productId"
    },  
    "tag": {
      "type": "belongsTo",
      "model": "Tag",
      "foreignKey": "tagId"
    }   
  },  
  #more stuff
}

common/models/tag.json

  {
      "name": "Tag",
      #more stuff
       "properties": {
         "name": {
         "type": "string",
         "required": true,
         "index": {
         "unique": true
       }
      },
      "relations": {
        "pictures": {
          "type": "hasMany",
          "model": "Pictures",
          "foreignKey": "tagId",
          "through": "PictureTags"
        }
        "products": {
          "type": "hasMany",
          "model": "Product",
          "foreignKey": "tagId",
          "through": "ProductTags"
        }
      },
      #more stuff
    }

如何按标签名称查询所有产品?例如。获取所有标签名称为“XYZ”的产品(如果我们可以使用“like”,甚至更好,以便查询不是完全匹配,而是“喜欢”)。 REST查询格式首选。

我试过看: https://docs.strongloop.com/display/public/LB/Include+filter 但我的包含过滤器会首先返回所有产品,并为它们添加标签信息。

编辑: 几次尝试:

curl --globoff http://localhost:3000/api/v1/Tags?filter[where][name][inq]=FirstTag&filter[where][name][inq]=ThirdTag&filter[include][products]

这一个直接来自文档 返回错误:

  

name属性包含无效条款{\“inq \”:\“FirstTag \”} \

curl --globoff http://localhost:3000/api/v1/Products?filter=[include][tags][name]=NonExistingTag
尽管如此

还会返回所有产品

curl -X GET "http://localhost:3000/api/v1/Products?filter[where]tags][name]=First" --globoff

返回此错误:     {       “错误”:{         “name”:“TypeError”,         “身份”:500,         “message”:“无法读取未定义的属性'类型',         “stack”:“TypeError:无法在PostgreSQL.toColumnValue中读取undefined \ n的属性'type'(/home/fabio/prj/fapl/src/loopback/node_modules/loopback-connector-postgresql/lib/postgresql.js:432 :11)\ n

我也看了看: https://docs.strongloop.com/display/public/LB/Where+filter 但是找不到任何相关的例子...... where子句是针对产品对象本身的,而不是针对相关的模型。

2 个答案:

答案 0 :(得分:1)

如果您的模型设置正确,您应该可以执行类似

的操作
//...snip...
Tag.findById(tagId, function(err, tag){

  // works for multiple relation types
  // hasMany, hasAndBelongsToMany, etc
  tag.products({}, function(err, productsWithTag) {
    if(err) return cb(err);
    // productsWithTag available here
  });

});
//...snip...

哪个应该返回该标签的所有产品。可以使用findById替换find(filter...),而不是通过名称或查询来获取标记实例。

请参阅底部的https://docs.strongloop.com/display/public/LB/HasAndBelongsToMany+relations以获取“添加到模型中的方法”以获取指导。还要检查您的模型json是否正确,并确定它是hasAndBelongsToMany还是hasManybelongsTo的组合最佳。

答案 1 :(得分:0)

我也在loopbackjs谷歌小组上提出了这个问题。

某人(Nuba Princigalli,如果你在这里,你应该发布你的解决方案作为答案,这样我就可以接受了......)发布了这个答案:

  

假设您的标签位于/ api / tags,只需在此处发出HTTP GET请求即可   / api / tags?filter = {“where”:{“id”:“1234”},“include”:“products”}“   使用like或regex自定义where子句以满足您的需求。

     

如果返回多个标记,则每个标记都有自己的列表   产品。如果您只想要一个产品列表,则可以合并它们   在客户端上,或通过两个步骤执行查询:查找匹配的所有标记   过滤器的位置,包括相关的ProductTag,然后使用它们   建立您想要的产品ID列表,然后找到所有产品   使用inq运算符。   https://docs.strongloop.com/display/public/LB/Where+filter#Wherefilter-inq   。无需自定义端点。

为了获得产品,不得不查询标签。此外,如果为产品分配了多个标签,并且我正在查询多个标签,我会多次获得相同的产品。

不太理想,但暂时对我们来说还不错!