Is list function a good candidate for my scenario? - couchdb

I have a view in couchDb that is defined like this
function (doc) {
if (doc.url) {
var a = new Date(doc.postedOn);
emit([a.toLocaleDateString(), doc.count, doc.userId], {
_id: doc.userId,
postTitle: doc.postTitle,
postSummary: doc.postSummary,
url: doc.url,
count: doc.count
});
}
};
This gives me the result in a format that I want.Sorted first by date then by count and then by userID.
However I have trouble querying it.What I want is to query this view just by userId.That is leave the date and the count parameter null.
_view/viewName?limit=20&descending=true&endkey=["","","userId"]
does not give me the desired result.
Should I be using list function to filter out the results of the view.Is there any impact on performance if I do this?
This quote from the definitive guide first gave me the idea that list functions could be used to filter and aggregate results.
The powerful iterator API allows for flexibility to filter and aggregate rows on the fly, as well as output raw transformations for an easy way to make Atom feeds, HTML lists, CSV files, config files, or even just modified JSON.

List function has nothing to do with your case. From the docs you've linked to yourself:
While Show functions are used to customize document presentation, List functions are used for same purpose, but against View functions results.
Show functions are used to represent documents in various formats, commonly as HTML page with nicer formatting. They can also be used to run server-side functions without requiring a pre-existing document.
To solve your problem just change the order of the emitted keys, putting userId first, i.e.:
[ doc.userId, a.toLocaleDateString(), doc.count ]
and update your query appropriately.
If changing the order of emitted keys is not an option, just create another view.

Related

How to best provide deeplinking to a firestore backed paginated list

I'm evaluating the feasibility to replace parts of our SQL database with Firestore and so far it's been a pleasure!
I'm wondering what's the best way to provide bookmarkable links to a given page in a list? I've successfully implemented paging, and found out that I need to maintain
lastVisible: firebase.firestore.DocumentSnapshot[] = []
to be able to traverse back and forth the paginated list like this:
if (this._paginator._pageIndex - 1 in this.lastVisible) {
return ref.orderBy('date', 'desc').startAfter(this.lastVisible[this._paginator._pageIndex - 1]).limit(this._paginator.pageSize)
} else {
return ref.orderBy('date', 'desc').limit(this._paginator.pageSize)
}
If I understand correctly, I can feed either the whole doc or the value used by the index to the startAfter and startAt methods. Either way, to provide a a deeplink for the list, opened at page 245, I need to pass 245 values in the URL to be able to pull this one off?
Or then I need to requery all the items from 0 to xxx page and record all the last items?
Any thoughts how to best tackle this one?
Is there any way to just use the numeric indexes, that can be calculated from the page and page size?

Get list of inventory items from NetSuite

Is there a way to retrieve an array or list of specific inventory items in NetSuite with one call? I can not seem to find any documentation regarding this. I have gone through the SuiteTalk training course and it does not contain any information on retrieving a list of items without the internalID.
On page 73 of this document there is a function getInventoryItemList(itemKeysArray) that is called with an array of inventory item id's. However this function does not exist anywhere and I am assuming is a custom function but they never show the code for it.
The only two ways I can see doing this would be to pull every single inventory item out of NetSuite and import the internalID's into our local database, this seems like a lot of extra work to me. Another option I thought of is to loop over an array of the line items and perform an ItemSearchBasic for every element and get the internalID that way, this seems like a worse idea than just storing them in the local database. I am hoping someone can confirm and show me if there is a much easier way of doing what I need.
Here is a version of what I use when I need to get the a list of items (minus company specific data). I just removed our data, and set it build/return an array. This is in SuiteScript 2.0, just FYI.
require(['N/search','N/record'],function(search,record){
function buildItemArray(){
var itemArray=[];
searchItems();
itemArray=runSearch(itemArray);
deleteSearch();
log.debug(itemArray);
}
function searchItems(context){
var itemSearch=search.create({
type:search.Type.INVENTORY_ITEM,
title:'Inventory_Item_Search',
id:'customsearch_inventory_item_search',
columns:['internalid','itemid'],
filters:['isinactive','is','F']
});
itemSearch.save();
}
function runSearch(itemArray){
var mySearch=search.load({id:'customsearch_inventory_item_search'});
mySearch.run().each(function(result){
var item={};
item.itemID=result.getValue({name:'itemid'});
item.internalID=result.getValue({name:'internalid'});
itemArray.push(item);
return true;
});
return itemArray;
}
function deleteSearch(){
search.delete({id:'customsearch_inventory_item_search'});
}
buildItemArray();
});
There are a number of ways to do that but the idea of collecting the item ids from the line items is the one I normally use.
You can then use GetList to retrieve details about each item.

Alfresco webscript (js) and pagination

I have a question about the good way to use pagination with Alfresco.
I know the documentation (https://wiki.alfresco.com/wiki/4.0_JavaScript_API#Search_API)
and I use with success the query part.
I mean by that that I use the parameters maxItems and skipCount and they work the way I want.
This is an example of a query that I am doing :
var paging =
{
maxItems: 100,
skipCount: 0
};
var def =
{
query: "cm:name:test*"
page: paging
};
var results = search.query(def);
The problem is that, if I get the number of results I want (100 for example), I don't know how to get the maxResults of my query (I mean the total amount of result that Alfresco can give me with this query).
And I need this to :
know if there are more results
know how many pages of results are lasting
I'm using a workaround for the first need : I'm doing a query for (maxItems+1), and showing only maxItems. If I have maxItems+1, I know that there are more results. But this doesn't give me the total amount of result.
Do you have any idea ?
With the javascript search object you can't know if there are more items. This javascript object is backed by the class org.alfresco.repo.jscript.Search.java. As you can see the query method only returns the query results without any extra information. Compare it with org.alfresco.repo.links.LinkServiceImpl which gives you results wrapped in PagingResults.
So, as javacript search object doesn't provide hasMoreItems info, you need to perform some workaround, for instance first query without limits to know the total, and then apply pagination as desired.
You can find how many objects have been found by your query simply calling
results.length
paying attention to the fact that usually queries have a configured maximum result set of 1000 entries to save resources.
You can change this value by editing the <alfresco>/tomcat/webapps/alfresco/WEB_INF/classes/alfresco/repository.properties file.
So, but is an alternative to your solution, you can launch a query with no constraints and obtain the real value or the max results configured.
Then you can use this value to devise how many pages are available basing you calculation on the number of results for page.
Then dinamically pass the number of the current page to the builder of your query def and the results variable will contain the corresponding chunk of data.
In this SO post you can find more information about pagination.

Mongoose: Only return one embedded document from array of embedded documents

I've got a model which contains an array of embedded documents. This embedded documents keeps track of points the user has earned in a given activity. Since a user can be a part of several activities or just one, it makes sense to keep these activities in an array. Now, i want to extract the hall of fame, the top ten users for a given activity. Currently i'm doing it like this:
userModel.find({ "stats.activity": "soccer" }, ["stats", "email"])
.desc("stats.points")
.limit(10)
.run (err, users) ->
(if you are wondering about the syntax, it's coffeescript)
where "stats" is the array of embedded documents/activeties.
Now this actually works, but currently I'm only testing with accounts who only has one activity. I assume that something will go wrong (sorting-wise) once a user has more activities. Is there anyway i can tell mongoose to only return the embedded document where "activity" == "soccer" alongside the top-level document?
Btw, i realize i can do this another way, by having stats in it's own collection and having a db-ref to the relevant user, but i'm wondering if it's possible to do it like this before i consider any rewrites.
Thanks!
You are correct that this won't work once you have multiple activities in your array.
Specifically, since you can't return just an arbitrary subset of an array with the element, you'll get back all of it and the sort will apply across all points, not just the ones "paired" with "activity":"soccer".
There is a pretty simple tweak that you could make to your schema to get around this though. Don't store the activity name as a value, use it as the key.
{ _id: userId,
email: email,
stats: [
{soccer : points},
{rugby: points},
{dance: points}
]
}
Now you will be able to query and sort like so:
users.find({"stats.soccer":{$gt:0}}).sort({"stats.soccer":-1})
Note that when you move to version 2.2 (currently only available as unstable development version 2.1) you would be able to use aggregation framework to get the exact results you want (only a particular subset of an array or subdocument that matches your query) without changing your schema.

Sorting on date after querying on multiple specific keys

Document structure:
{
"Type":"post"
"LastModified":"2010-11-01 21:55",
"CategoryID":3,
"ID":12
}
Having a bunch of different post docs in different categories is great. But I can't seem to figure out how to make a view which returns the documents ordered by date, when selecting the ones in, e.g., category 3 and 5. The categories are not known, the limit query should work still.
I've tried different approaches to the view but nothing comes close to achieving the desired result.
In SQL it could probably be done by something like this:
SELECT * FROM document WHERE document.CategoryID in (3,5) ORDER BY document.LastModified DESC;
I could just query a view like this the required number of times, manually sorting and paging the data:
function(doc) {
emit(doc.CategoryID, doc.ID);
}
So does anyone know if it's possible to avoid doing that and just have couchdb be a bit smarter?
I can think of 2 possible solutions.
Emit both CategoryID and LastModified in the map function.
function(doc) {
emit([doc.CategoryID, doc.LastModified], null);
}
Now you can query the view for ?startkey=[3]&endkey=[3, {}] to get all the docs with CategoryID=3 sorted by LastModified. To get docs for multiple CategoryIDs, you need to merge the sorted results.
Use couchdb-lucene to build the index. couchdb-lucene can handle complex queries.

Resources