node-odata icon indicating copy to clipboard operation
node-odata copied to clipboard

query the example of 'complex-resource'

Open shoringfan10 opened this issue 8 years ago • 8 comments

I have tried to add some mock data for the complex-resource example, which has its structure as,

var order = {
  custom: {
    id: String,
    name: String
  },
  orderItems: [{
    quantity: Number,
    product: {
      id: String,
      name: String,
      price: Number
    }
  }]
};

The question is, how can I get the result that the orderItems have their products with the prices higher than 10.00, for example?

I have tried the queries like, without luck.

1. GET orders?$filter=price gt 10
2. GET orders?$filter=product/price gt 10
3. GET orders?$filter=orderItems/product/price gt 10

the results are always empty, was this a bug or something I was missing, any ideas?

{"value":[]}

The mock data:

{ "_id" : "fb107243-5f4d-4d47-8b35-245fa85127cd", "orderItems" : [ { "quantity" : 100, "_id" : ObjectId("57e303cdd70bda6419c9922d"), "product" : { "id" : "item123", "name" : "ITEMA", "price" : 10 } } ], "custom" : { "id" : "abc123", "name" : "ABC" } }
{ "_id" : "1c1ceeea-8c75-443e-8706-fa696ec5acf6", "orderItems" : [ { "quantity" : 200, "_id" : ObjectId("57e30426d70bda6419c9922e"), "product" : { "id" : "item234", "name" : "ITEMB", "price" : 15 } } ], "custom" : { "id" : "bcd123", "name" : "BCD" } }
{ "_id" : "a8dd0f23-46d9-4f6e-bffa-9709e7c23b87", "orderItems" : [ { "quantity" : 300, "_id" : ObjectId("57e30454d70bda6419c9922f"), "product" : { "id" : "item345", "name" : "ITEMC", "price" : 20 } } ], "custom" : { "id" : "efg123", "name" : "EFG" } }
{ "_id" : "316efd3f-0b30-4ad1-ac22-2640a613142e", "orderItems" : [ { "quantity" : 400, "_id" : ObjectId("57e30474d70bda6419c99230"), "product" : { "id" : "item456", "name" : "ITEMD", "price" : 30 } } ], "custom" : { "id" : "hij123", "name" : "HIJ" } }

shoringfan10 avatar Sep 21 '16 22:09 shoringfan10

Sorry, it's not support this feature, it can only support a simple model query. I will try to add it on this weekend.

zackyang000 avatar Sep 21 '16 23:09 zackyang000

try

GET orders?$filter=orderItems.product.price gt 10

A example.

zackyang000 avatar Sep 25 '16 00:09 zackyang000

Hi @TossShinHwa, many thanks for your quick reply!

It seems working well before I add following new orderItems to the collection,

{"orderItems":[{"quantity":1000,"product":{"id":"item777","name":"ITEM7","price":10}},{"quantity":2000,"product":{"id":"item888","name":"ITEM8","price":15}},{"quantity":3000,"product":{"id":"item999","name":"ITEM9","price":20}}],"custom":{"id":"xyz123","name":"XZY"}}

In this case, if I query,

GET orders?$filter=orderItems.product.price lt 15

The response would always include the entire array, if there is at least one price in the array matches the query. I wonder if I have to use $expand or any/all functions to further filter (refine) the result in this case?

The response of above query (price less than 15):

{"value":[{"orderItems":[{"quantity":100,"product":{"id":"item123","name":"ITEMA","price":10},"id":"57e303cdd70bda6419c9922d"}],"custom":{"id":"abc123","name":"ABC"},"id":"fb107243-5f4d-4d47-8b35-245fa85127cd"},**{"orderItems":[{"quantity":1000,"product":{"id":"item777","name":"ITEM7","price":10}},{"quantity":2000,"product":{"id":"item888","name":"ITEM8","price":15}},{"quantity":3000,"product":{"id":"item999","name":"ITEM9","price":20}}]**,"custom":{"id":"xyz123","name":"XZY"},"id":"57e941c0a8dbeb4c8c8f317c"}]}

The response of query (price greater than 15):

{"value":[{"orderItems":[{"quantity":300,"product":{"id":"item345","name":"ITEMC","price":20},"id":"57e30454d70bda6419c9922f"}],"custom":{"id":"efg123","name":"EFG"},"id":"a8dd0f23-46d9-4f6e-bffa-9709e7c23b87"},{"orderItems":[{"quantity":400,"product":{"id":"item456","name":"ITEMD","price":30},"id":"57e30474d70bda6419c99230"}],"custom":{"id":"hij123","name":"HIJ"},"id":"316efd3f-0b30-4ad1-ac22-2640a613142e"},**{"orderItems":[{"quantity":1000,"product":{"id":"item777","name":"ITEM7","price":10}},{"quantity":2000,"product":{"id":"item888","name":"ITEM8","price":15}},{"quantity":3000,"product":{"id":"item999","name":"ITEM9","price":20}}]**,"custom":{"id":"xyz123","name":"XZY"},"id":"57e941c0a8dbeb4c8c8f317c"}]}

shoringfan10 avatar Sep 26 '16 16:09 shoringfan10

Unfortunately, it's not support $expand / all / any to query entities. But there has a way to make it work even it ugly.

You can add a ACTION for this resource, it's use mongoDB API to filter data. example:

    server.resource('order', { product: [{ price: Number }] })
    .action('/all-item-greater', (req, res, next) => {
      const { price } = req.query;
      const $elemMatch = { price: { $gt: price } };
      server.resources.order.find()
      .select({ product: { $elemMatch } })
      .exec((err, data) => res.jsonp(data));
    });

Full version.

zackyang000 avatar Sep 27 '16 14:09 zackyang000

Thanks for the reply! but I met a small problem with const { price },

  const { price }  = req.query;
        ^

SyntaxError: Unexpected token {
    at exports.runInThisContext (vm.js:53:16)
    at Module._compile (module.js:373:25)
    at Object.Module._extensions..js (module.js:416:10)
    at Module.load (module.js:343:32)
    at Function.Module._load (module.js:300:12)
    at Function.Module.runMain (module.js:441:10)
    at startup (node.js:139:18)
    at node.js:974:3

shoringfan10 avatar Sep 30 '16 15:09 shoringfan10

ES6 syntax:

const { price }  = req.query;

Same as ES5 syntax:

var price = req.query.price;

zackyang000 avatar Sep 30 '16 23:09 zackyang000

Hi ! The ES5 syntax seems working, whereas the query cannot get a result in my test..

GET orders(316efd3f-0b30-4ad1-ac22-2640a613142e)/all-item-greater?price=10

The response,

Cannot GET /orders(316efd3f-0b30-4ad1-ac22-2640a613142e)/all-item-greater?price=10

The data, I assume ACTION should also work in the case of non-multiple orderItems.

GET orders(316efd3f-0b30-4ad1-ac22-2640a613142e)/

{"orderItems":[{"quantity":400,"_id":"57e30474d70bda6419c99230","product":{"id":"item456","name":"ITEMD","price":30}}],"custom":{"id":"hij123","name":"HIJ"},"id":"316efd3f-0b30-4ad1-ac22-2640a613142e"}

shoringfan10 avatar Oct 03 '16 14:10 shoringfan10

Strange, it should be working. plz check your code is same as the example.

zackyang000 avatar Oct 04 '16 07:10 zackyang000