locked
Is the first entry Categories(0) or Categories(1) RRS feed

  • Question

  • Hi all;

    If you look at http://services.odata.org/Northwind/Northwind.svc/Categories the first entry is http://services.odata.org/Northwind/Northwind.svc/Categories(1)

    But if you look at http://services.odata.org/OData/OData.svc/Products the first entry is http://services.odata.org/OData/OData.svc/Products(0)

    We display the metadata of the service to the user and let them pick an item. If they select an entry or property, we want to give them back the first one.

    Can this be done by indexing? Or is it up to the server to decide if the are 0-based or 1-based? And if so, is our best bet to do http://services.odata.org/Northwind/Northwind.svc/Categories?$top=1

    ??? - thanks - dave


    Who will win The International Collegiate Programming Championships?

    Thursday, September 13, 2012 9:23 PM

Answers

  • You can't. The closest you can get to is ~/Products?$top=1&$select=Price.

    Curious: Why do you need this?

    Thanks,


    Vitek Karas [MSFT]

    • Marked as answer by DavidThielen Friday, September 14, 2012 11:50 PM
    • Unmarked as answer by DavidThielen Saturday, September 15, 2012 12:43 AM
    • Marked as answer by DavidThielen Monday, September 17, 2012 3:56 PM
    Friday, September 14, 2012 3:38 PM
    Moderator
  • In that case you will need to make two requests.

    One for just ~/Customers?$top=1 possibly with some select to not get the whole ting back.

    From it you read the edit/read link of the entity you got back. And using that you modify it to ask for that one property.

    But if you need to be able to build a single query like that upfront, I'm afraid that's currently not possible.

    Thanks,


    Vitek Karas [MSFT]

    • Marked as answer by DavidThielen Monday, September 17, 2012 3:56 PM
    Monday, September 17, 2012 3:54 PM
    Moderator

All replies

  • Hi,

    It's a bit more complicated :-)

    The ID of entity is completely up to the server. It doesn't have to be a number either. For example the Netflix Titles entity uses a string a key. Also, response to ~/EntitySet is not bound to return the entities in any particular order. In fact they can be returned in different order each time. (That said lot of server do return them in certain order, mainly because the underlying data sore returns them like that, for example most DB return them sorted by the primary index which is likely the key property).

    If the client wants a specific ordering, it needs to specify the $orderby.

    The $top and $skip is somewhere in between. The server is not bound to order the entities in any specific way, but it does need to return them in a stable order. Again, most servers will sort by key in this case, but it's not required, they can order by whatever they want, as long as it's stable (so that the client can use the $top and $skip to page through the data).

    If you want just one entity, add $top=1. It will likely always be the same entity (again based on the stable ordering), but it can change over time if the underlying DB changes (entities are added, removed, ...).

    Thanks,


    Vitek Karas [MSFT]

    • Marked as answer by DavidThielen Thursday, September 13, 2012 11:05 PM
    • Unmarked as answer by DavidThielen Thursday, September 13, 2012 11:16 PM
    Thursday, September 13, 2012 10:28 PM
    Moderator
  • $top=1 it is.

    thanks - dave


    Who will win The International Collegiate Programming Championships?

    Thursday, September 13, 2012 11:05 PM
  • Hi;

    I've spent 15 minutes and can't figure this out. If I want http://services.odata.org/OData/OData.svc/Products(0)/Price using $top=1, how do I structure it?

    http://services.odata.org/OData/OData.svc/Products/Price?$top=1 does not work. I've tried all kinds of things including $expand but can't come up with anything that works.

    ??? - thanks - dave


    Who will win The International Collegiate Programming Championships?

    Thursday, September 13, 2012 11:17 PM
  • Well - that query doesn't make sense.

    ~/Products(0) already return singleton (Always). That's also why you can do /Price on it. It is invalid to ask a query like ~/Products/Price.  And since it's a singleton (let alone a property value) you can't apply query options which work on sets, like $top, $skip, $filter and so on.

    $expand and $select do work on singletons, but only on entities. The type of the ~/Products(0)/Price query is in fact a decimal. So there are actually no query options which are applicable to it, it's a primitive value.

    You can do ~/Product(0)?$expand=Category&$select=Name,Category/Name on the other hand.

    Thanks,


    Vitek Karas [MSFT]

    Friday, September 14, 2012 7:59 AM
    Moderator
  • But is there a way to get http://services.odata.org/OData/OData.svc/Products(0)/Price in a way that uses $top=1 instead of (0) so it works for all services?

    I need to have a way to return the first (or to be more accurate, a single) value. How, based on what I know in the EDM, can I create a uri to get back a single price value?

    thanks - dave


    Who will win The International Collegiate Programming Championships?

    Friday, September 14, 2012 1:17 PM
  • You can't. The closest you can get to is ~/Products?$top=1&$select=Price.

    Curious: Why do you need this?

    Thanks,


    Vitek Karas [MSFT]

    • Marked as answer by DavidThielen Friday, September 14, 2012 11:50 PM
    • Unmarked as answer by DavidThielen Saturday, September 15, 2012 12:43 AM
    • Marked as answer by DavidThielen Monday, September 17, 2012 3:56 PM
    Friday, September 14, 2012 3:38 PM
    Moderator
  • Hey, I thought of that before I saw your email!!! Does this mean I've graduated to OData Beginner?

    thanks - dave


    Who will win The International Collegiate Programming Championships?

    Friday, September 14, 2012 11:52 PM
  • Hi again;

    Is there a way to do this to get a single property inside a complex property? That seems to not be doable.

    The purpose is we make it easy to place any property in a report. Doing so directly works well:

      • When there is only one record. For example, what if an OData service at data.gov had eop/president/name/first - there's only 1.
      • From say ~/Product you want Category/Description/Name - there's only one.
      • Quick way to demonstrate getting a property.

    thanks - dave


    Who will win The International Collegiate Programming Championships?

    Saturday, September 15, 2012 12:47 AM
  • Sure - just access it like any other property:

    http://odata.netflix.com/v2/Catalog/Titles('13aly')/BoxArt/SmallUrl

    (The BoxArt is a complex property).

    Thanks,


    Vitek Karas [MSFT]

    Sunday, September 16, 2012 11:04 AM
    Moderator
  • Hi Vitek;

    The problem is I need to return SmallUrl knowing only the EDM. For this use case I have not ready any data because I am creating a select, not working off of a select.

    Is there a way to do it similiar to http://services.odata.org/OData/OData.svc/Suppliers?$top=1&$select=Address/Street

    http://services.odata.org/OData/OData.svc/Suppliers?$top=1&$select=Address works great, but then returning the value for street - I can't figure out how to get that part as a value.

    thanks - dave


    Who will win The International Collegiate Programming Championships?

    Monday, September 17, 2012 1:50 PM
  • Hi,

    I'm still struggling to understand why you need to be able to request what is effectively a random example of a value from the service. The $top=1 doesn't guarantee anything about what record it will return, just that it will return at most one record, but it could be the first or the last or anything in between.

    EDM itself will basically tell you everything you need to know about the property up front without requesting a sample value. You will get to know its type, nullability, how to address it, it's name, ...

    Requesting a random sample will not tell you anything interesting. You might get a value, but from your point of view it's just a random value which happens to exist in the data. Not much more info that the type from EDM. But that's when you're lucky. If you're unlucky you might get a null (assuming the property is nullable), in which case it's already less useful. But if you're really unlucky, you might not get the property at all. If the URL is a bit more complicated, for example ~/Products(1)/Category?$select=Name, if the Category property is null, it will return a 404.

    So the only case, where random sampling might be of some use are open properties, since EDM doesn't tell you anything about those. But to be able to sample them, you need to know the name (or request the parent entity and enumerate them). And even if you do get back a sample, nothing guarantees that another entity in the same set will have such a property and it will be of the same type.

    To answer your specific question, $select doesn't allow subsetting anything but entity properties. So it treats complex values as opaque atomic values. That's why $select=Address works, but you can't limit what parts of address to return.

    Thanks,


    Vitek Karas [MSFT]

    Monday, September 17, 2012 2:24 PM
    Moderator
  • Hi Vitek;

    It is somewhat common that there will be exactly 1 entry for a given select. In that case it works well. Sometimes it's a table that by definition has just one row (like the version of the data).

    Often it's that for a parent select, child selects are unique (for an Employee node, I then want Address/Street). In that case I have the ID uri for the Employee, but the architecture of our system is such that I don't have a way to pull that ID uri down.

    thanks - dave


    Who will win The International Collegiate Programming Championships?

    Monday, September 17, 2012 3:34 PM
  • In that case you will need to make two requests.

    One for just ~/Customers?$top=1 possibly with some select to not get the whole ting back.

    From it you read the edit/read link of the entity you got back. And using that you modify it to ask for that one property.

    But if you need to be able to build a single query like that upfront, I'm afraid that's currently not possible.

    Thanks,


    Vitek Karas [MSFT]

    • Marked as answer by DavidThielen Monday, September 17, 2012 3:56 PM
    Monday, September 17, 2012 3:54 PM
    Moderator
  • That's what I was afraid of. That's going to be a nasty performance hit.

    thanks - dave


    Who will win The International Collegiate Programming Championships?

    Monday, September 17, 2012 3:56 PM