what jsom getitems for sharepoint caml spquery

jsom - sharepoint csom assemblies



¿Cuál es la mejor manera de recuperar valores distintos/únicos usando SPQuery? (6)

Tengo una lista que se ve así:

Movie Year ----- ---- Fight Club 1999 The Matrix 1999 Pulp Fiction 1994

Usando CAML y el objeto SPQuery, necesito obtener una lista distinta de elementos de la columna Año que completará un control desplegable.

La búsqueda por ahí no parece ser una forma de hacerlo dentro de la consulta CAML. Me pregunto cómo han ido las personas para lograr esto.


¿Puedes cambiar de SPQuery a SPSiteDataQuery? Deberías poder hacerlo, sin ningún problema.

Después de eso, puedes usar el comportamiento estándar de ado.net:

SPSiteDataQuery query = new SPSiteDataQuery(); /// ... populate your query here. Make sure you add Year to the ViewFields. DataTable table = SPContext.Current.Web.GetSiteData(query); //create a new dataview for our table DataView view = new DataView(table); //and finally create a new datatable with unique values on the columns specified DataTable tableUnique = view.ToTable(true, "Year");


No hay DISTINCT en CAML para llenar su menú desplegable intente utilizar algo como:

foreach (SPListItem listItem in listItems) { if ( null == ddlYear.Items.FindByText(listItem["Year"].ToString()) ) { ListItem ThisItem = new ListItem(); ThisItem.Text = listItem["Year"].ToString(); ThisItem.Value = listItem["Year"].ToString(); ddlYear.Items.Add(ThisItem); } }

Asume que su menú desplegable se llama ddlYear.


Otra forma de hacerlo es usar DataView.ToTable-Method: su primer parámetro es el que hace que la lista sea distinta.

SPList movies = SPContext.Current.Web.Lists["Movies"]; SPQuery query = new SPQuery(); query.Query = "<OrderBy><FieldRef Name=''Year'' /></OrderBy>"; DataTable tempTbl = movies.GetItems(query).GetDataTable(); DataView v = new DataView(tempTbl); String[] columns = {"Year"}; DataTable tbl = v.ToTable(true, columns);

Luego puede continuar usando DataTable tbl.


Si desea vincular los distintos resultados a un DataSource de, por ejemplo, un Repeater y retener el elemento real mediante el método e.Item.DataItem de los eventos de ItemDataBound, el método DataTable no funcionará. En cambio, y además, cuando no se desea vincular a un DataSource, también se puede usar Linq para definir los valores distintos.

// Retrieve the list. NEVER use the Web.Lists["Movies"] option as in the other examples as this will enumerate every list in your SPWeb and may cause serious performance issues var list = SPContext.Current.Web.Lists.TryGetList("Movies"); // Make sure the list was successfully retrieved if(list == null) return; // Retrieve all items in the list var items = list.GetItems(); // Filter the items in the results to only retain distinct items in an 2D array var distinctItems = (from SPListItem item in items select item["Year"]).Distinct().ToArray() // Bind results to the repeater Repeater.DataSource = distinctItems; Repeater.DataBind();

Recuerde que, dado que no hay compatibilidad CAML para consultas distintas, cada muestra proporcionada en esta página recuperará TODOS los elementos de la lista SPList. Esto puede estar bien para listas más pequeñas, pero para listas con miles de elementos de lista, esto seriamente un asesino de rendimiento. Lamentablemente, no hay una forma más optimizada de lograr lo mismo.


Estaba considerando este problema más temprano hoy, y la mejor solución que se me ocurre utiliza el siguiente algoritmo (lo siento, no hay código en este momento):

L is a list of known values (starts populated with the static Choice options when querying fill-in options, for example) X is approximately the number of possible options 1. Create a query that excludes the items in L 1. Use the query to fetch X items from list (ordered as randomly as possible) 2. Add unique items to L 3. Repeat 1 - 3 until number of fetched items < X

Esto reduciría la cantidad total de artículos devueltos significativamente, a costa de realizar más consultas.

No importa mucho si X es completamente preciso, pero la aleatoriedad es bastante importante. Esencialmente, la primera consulta probablemente incluya las opciones más comunes, por lo que la segunda consulta las excluirá y es probable que incluya las siguientes opciones más comunes, y así sucesivamente a través de las iteraciones.

En el mejor de los casos, la primera consulta incluye todas las opciones, luego la segunda consulta estará vacía. (X elementos recuperados en total, más de 2 consultas)

En el peor de los casos (por ejemplo, la búsqueda está ordenada por las opciones que estamos buscando, y hay más de X elementos con cada opción) realizaremos tantas consultas como opciones. Devolviendo aproximadamente X * X artículos en total.


Después de encontrar una publicación tras otra sobre cómo esto era imposible, finalmente encontré la manera. Esto ha sido probado en SharePoint Online. Aquí hay una función que le dará todos los valores únicos para una columna. Solo requiere que ingrese la Id de la lista, Id de la vista, el nombre de la lista interna y una función de devolución de llamada.

function getUniqueColumnValues(listid, viewid, column, _callback){ var uniqueVals = []; $.ajax({ url: _spPageContextInfo.webAbsoluteUrl + "/_layouts/15/filter.aspx?ListId={" + listid + "}&FieldInternalName=" + column + "&ViewId={" + viewid + "}&FilterOnly=1&Filter=1", method: "GET", headers: { "Accept": "application/json; odata=verbose" } }).then(function(response) { $(response).find(''OPTION'').each(function(a,b){ if ($(b)[0].value) { uniqueVals.push($(b)[0].value); } }); _callback(true,uniqueVals); },function(){ _callback(false,"Error retrieving unique column values"); });

}