I have one problem regarding mapping values from mongodb from document having values (_id,author,title,content) representing one blog, to angular class with fields id,author,title,content; namely, using pipe and map operators in angular i can map the blog document, but without _id field from mongodb.
I thought i figured out how pipe and map works, but in my case I have one observable object which should be return, which complicates things for me. I read some documentation on https://angular.io/guide/rx-library but haven't quite figured out how to apply that in my case.
getBlogs(username): Observable<Blog[]> {
return this.http.get(`${this.uri}/getBlogs/${username}`).pipe(
map ((data: Blog[]) => {
this.blogs = data;
return this.blogs;
}
));
}
Here in the code, I am trying to return all blogs belonging to one user with its username, and here I am mapping (i guess) all fields of data-mongodb documents with corresponding fields of blog. But all fields get mapped except id field (with Object_id field of mongodb).
My blog class look like:
export class Blog {
id: string;
author: string;
title: string;
content: string;
public constructor() {}
}
I would greatly appreciate if anyone knows how can i resolve this.I am using mongodb 3.2 , angular cli 7.3.8 and angular 7.2.14.
Related
I'm trying to export Umbraco Forms data to CSV, in the exact format generated when you export from the Entries table UI, and I'm trying to do this strictly from code. End result is I would like to run as a task to export data daily or every few hours, and save that .csv file to a folder on the server. This would be for bulk importing into other systems, and a Forms Workflow won't work in this case.
My original approach was to try and do this in SQL, but Forms data would be difficult to work with since it's a in a mix of JSON and native SQL data. I'm not running SQL Server 2016 so no JSON support.
I've been searching through the Forms API and found a few things that might help, but can't seem to find what I need. So far I've tried:
Umbraco.Forms.Data.Storage.RecordStorage.GetAllRecords()
This gets the records, but unsure where to get the field names. I don't even see them in the UF tables. I can generate JSON output via GenerateRecordDataAsJson() but only get Guids for field names.
I've tried looping through the above Record collection and manually working with individual items, and I've tried the RecordStorage.BuildRecord() method hoping that would assemble the data, but no luck there either.
You have to get the field names using the API. When Forms was still Contour, EVERYTHING was in the database, making it easy(ish) to query stuff like this.
I think you need to use FormStorage to get the details of the form and you should be able to get the fields from that.
Thought I'd share an example for Umbraco 8 and Forms 8.4.1 since I just ran into this same requirement recently.
public class ExportController : UmbracoApiController
{
IRecordReaderService RecordReaderService;
public ExportController(
IRecordReaderService recordReaderService)
{
RecordReaderService = recordReaderService;
}
[HttpGet]
public void Export()
{
var formId = new System.Guid("f9ea767a-0e4e-4c90-85f1-53ef42c60793");
var pageSize = 50;
var formResults = RecordReaderService.GetRecordsFromForm(formId, 1, pageSize);
foreach (var entry in formResults.Items)
{
var firstName = entry.ValueAsString("firstName"); // Use field alias
// Output data or other
}
}
}
I am using Grails 2.2.4 to build a web application, and now I am having a complex problem with Grails withCriteria operation. I have 3 classes as below:
class Person {
int id
String name
Set<Car> cars = [] // One-to-many relationship
Company currentCompany // One-to-one relationship
}
class Car {
int id
String manufacturer
String brand
double price
Person owner
}
class Company {
int id
String name
Set<Person> employees = []
}
And now I want to query data from Person as root class along with associated data like this:
List result = Person.withCriteria {
projections {
property('id')
property('name')
createAlias('cars', 'c', CriteriaSpecification.LEFT_JOIN)
property('c.brand')
createAlias('currentCompany', 'com', CriteriaSpecification.LEFT_JOIN)
property('com.name')
}
lt('id', 10L)
resultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY)
}
And the problem is, I don't know how to transform deeply the result data to a List of persons to make sure every single element contains its data as the class structure. I tried many methods like
resultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY)
resultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP)
resultTransformer(CriteriaSpecification.aliasToBean(Person.class))
but nothing worked as I expected.
Does Grails 2.2.4 support this? If yes so what is the correct syntax?
Thank you so much.
Actually, after researching many articles, Grails documentation and even its source code, I think the best way to do this is implementing a custom transformer for my own purpose. The most difficult thing here is how to transform data to association objects and gather them to collection inside the root entity. And I have created one here:
http://www.mycodestock.com/code/10333/
Hope it helps you guys who may need something like mine.
My Grails app is using the searchable plugin, which builds on Compass and Lucene to provide search functionality. I have two searchable classes, say Author and Book. I have mapped these classes to the search index, so that only certain fields can be searched.
To perform a search across both classes I simply call
def results = searchableService.search(query)
One of the nice features of doing the search across both class simultaneously, is that the results object includes metadata about number of results included, number of results available, pagination details etc.
I recently added a boolean approved flag to the Book class and I never want unapproved books to appear in the search results. One option is to replace the call above with:
def bookResults = Book.search(query + " approved:1")
def authorResults = Author.search(query)
However, I now need to figure out how to combine the metadata for both results, which is likely to be tricky (particularly pagination).
Is there a way to search across Book and Author with a single query, but only return approved books?
Do you want to be able to find authors or do you want to find books with a given author?
If you want to find books with a given author, you can configure your domain classes in the following way:
class Author {
String name
...
static searchable = {
root false
}
}
this will result in excluding the Author from the searchableService.search(query)-result and you'll find field names like $/Book/Author/name in your index. (use luke to examine your index: http://code.google.com/p/luke/).
You can change the name of those fields by configuring a better prefix in your Book-class:
class Book {
String name
Author author
...
static searchable = {
author component: [prefix: 'author']
}
}
this will change the name of the field in the index to bookauthor.
If you now search with searchableService.search(query), you'll find all books where the name of the book or the name of the author contains the search term. You can even restrict the search to a given author by using the authorname:xyz syntax.
If you really would like to mix the search results, I only know the solution you already mentioned: mixing both results with your own code, but I guess it will be hard to mix the scoring of the hits in a good way.
Update to your response: Here's my pagination code...
.gsp:
<div class="pagination">
<g:paginate total="${resultsTotal}" params="[q: params.q]"/>
</div>
controller:
result = searchableService.search(params.q, params)
[
resultList: result.results,
resultsTotal: result.total
]
So if you just merge the results of your two searches and add the result.totals, this could work for you.
I've created a test app and came to the following solution. maybe it helps...
if the property approved only has the states 0 and 1, the following query will work:
def results = searchableService.search(
"(${query} AND approved:1) OR (${query} -approved:0 -approved:1)"
)
I guess this can be reformulated in a better way if you don't use the QueryParser but the BooleanQueryBuilder.
BTW: if you add a method like
String getType() { "Book" }
and
String getType() { "Author" }
To your domains, you can even configure your search to do it like this
def results = searchableService.search(
"(${query} AND approved:1) OR (${query} AND type:Author)"
)
I have an ASP.NET MVC website. In my backend I have a table called People with the following columns:
ID
Name
Age
Location
... (a number of other cols)
I have a generic web page that uses model binding to query this data. Here is my controller action:
public ActionResult GetData(FilterParams filterParams)
{
return View(_dataAccess.Retrieve(filterParams.Name, filterParams.Age, filterParams.location, . . .)
}
which maps onto something like this:
http://www.mysite.com/MyController/GetData?Name=Bill .. .
The dataAccess layer simply checks each parameter to see if its populated to add to the db where clause. This works great.
I now want to be able to store a user's filtered queries and I am trying to figure out the best way to store a specific filter. As some of the filters only have one param in the queryString while others have 10+ fields in the filter I can't figure out the most elegant way to storing this query "filter info" into my database.
Options I can think of are:
Have a complete replicate of the table (with some extra cols) but call it PeopleFilterQueries and populate in each record a FilterName and put the value of the filter in each of field (Name, etc)
Store a table with just FilterName and a string where I store the actual querystring Name=Bill&Location=NewYork. This way I won't have to keep adding new columns if the filters change or grow.
What is the best practice for this situation?
If the purpose is to save a list of recently used filters, I would serialise the complete FilterParams object into an XML field/column after the model binding has occurred. By saving it into a XML field you're also giving yourself the flexibility to use XQuery and DML should the need arise at a later date for more performance focused querying of the information.
public ActionResult GetData(FilterParams filterParams)
{
// Peform action to get the information from your data access layer here
var someData = _dataAccess.Retrieve(filterParams.Name, filterParams.Age, filterParams.location, . . .);
// Save the search that was used to retrieve later here
_dataAccess.SaveFilter(filterParams);
return View(someData);
}
And then in your DataAccess Class you'll want to have two Methods, one for saving and one for retrieving the filters:
public void SaveFilter(FilterParams filterParams){
var ser = new System.Xml.Serialization.XmlSerializer(typeof(FilterParams));
using (var stream = new StringWriter())
{
// serialise to the stream
ser.Serialize(stream, filterParams);
}
//Add new database entry here, with a serialised string created from the FilterParams obj
someDBClass.SaveFilterToDB(stream.ToString());
}
Then when you want to retrieve a saved filter, perhaps by Id:
public FilterParams GetFilter(int filterId){
//Get the XML blob from your database as a string
string filter = someDBClass.GetFilterAsString(filterId);
var ser = new System.Xml.Serialization.XmlSerializer(typeof(FilterParams));
using (var sr = new StringReader(filterParams))
{
return (FilterParams)ser.Deserialize(sr);
}
}
Remember that your FilterParams class must have a default (i.e. parameterless) constructor, and you can use the [XmlIgnore] attribute to prevent properties from being serialised into the database should you wish.
public class FilterParams{
public string Name {get;set;}
public string Age {get;set;}
[XmlIgnore]
public string PropertyYouDontWantToSerialise {get;set;}
}
Note: The SaveFilter returns Void and there is no error handling for brevity.
Rather than storing the querystring, I would serialize the FilterParams object as JSON/XML and store the result in your database.
Here's a JSON Serializer I regularly use:
using System.IO;
using System.Runtime.Serialization.Json;
using System.Text;
namespace Fabrik.Abstractions.Serialization
{
public class JsonSerializer : ISerializer<string>
{
public string Serialize<TObject>(TObject #object) {
var dc = new DataContractJsonSerializer(typeof(TObject));
using (var ms = new MemoryStream())
{
dc.WriteObject(ms, #object);
return Encoding.UTF8.GetString(ms.ToArray());
}
}
public TObject Deserialize<TObject>(string serialized) {
var dc = new DataContractJsonSerializer(typeof(TObject));
using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(serialized)))
{
return (TObject)dc.ReadObject(ms);
}
}
}
}
You can then deserialize the object and pass it your data access code as per your example above.
You didn't mention about exact purpose of storing the filter.
If you insist to save filter into a database table, I would have following structure of the table.
FilterId
Field
FieldValue
An example table might be
FilterId Field FieldValue
1 Name Tom
1 Age 24
1 Location IL
3 Name Mike
...
The answer is much more simple than you are making it:
Essentially you should store the raw query in its own table and relate it to your People table. Don't bother storing individual filter options.
Decide on a value to store (2 options)
Store the URL Query String
This id be beneficial if you like open API-style apps, and want something you can pass nicely back and forth from the client to the server and re-use without transformation.
Serialize the Filter object as a string
This is a really nice approach if your purpose for storing these filters remains entirely server side, and you would like to keep the data closer to a class object.
Relate your People table to your Query Filters Table:
The best strategy here depends on what your intention and performance needs are. Some suggestions below:
Simple filtering (ex. 2-3 filters, 3-4 options each)
Use Many-To-Many because the number of combinations suggests that the same filter combos will be used lots of times by lots of people.
Complex filtering
Use One-To-Many as there are so many possible individual queries, it less likely they are to be reused often enough to make the extra-normalization and performance hit worth your while.
There are certainly other options but they would depend on more detailed nuances of your application. The suggestions above would work nicely if you are say, trying to keep track of "recent queries" for a user, or "user favorite" filtering options...
Personal opinion
Without knowing much more about your app, I would say (1) store the query string, and (2) use OTM related tables... if and when your app shows a need for further performance profiling or issues with refactoring filter params, then come back... but chances are, it wont.
GL.
In my opinion the best way to save the "Filter" is to have some kind of json text string with each of the "columns names"
So you will have something in the db like
Table Filters
FilterId = 5 ; FilterParams = {'age' : '>18' , ...
Json will provide a lot of capabilities, like the use of age as an array to have more than one filter to the same "column", etc.
Also json is some kind of standard, so you can use this "filters" with other db some day or to just "display" the filter or edit it in a web form. If you save the Query you will be attached to it.
Well, hope it helps!
Assuming that a nosql/object database such as Berkeley DB is out of the question, I would definitely go with option 1. Sooner or later you'll find the following requirements or others coming up:
Allow people to save their filters, label, tag, search and share them via bookmarks, tweets or whatever.
Change what a parameter means or what it does, which will require you to version your filters for backward compatibility.
Provide auto-complete functions over filters, possibly using a user's filter history to inform the auto-complete.
The above will be somewhat harder to satisfy if you do any kind of binary/string serialization where you'll need to parse the result and then process them.
If you can use a NoSql DB, then you'll get all the benefits of a sql store plus be able to model the 'arbitrary number of key/value pairs' very well.
Have thought about using Profiles. This is a build in mechanism to store user specific info. From your description of your problem its seems a fit.
Profiles In ASP.NET 2.0
I have to admit that M$ implementation is a bit dated but there is essentially nothing wrong with the approach. If you wanted to roll your own, there's quite a bit of good thinking in their API.
Just building a quick, simple site with MVC 3 RC2 and RavenDB to test some things out.
I've been able to make a bunch of projects, but I'm curious as to how Html.ActionLink() handles a raven DB ID.
My example: I have a Document called "reasons" (a reason for something, just text mostly), which has reason text and a list of links. I can add, remove, and do everything else fine via my repository.
Below is the part of my razor view that lists each reason in a bulleted list, with an Edit link as the first text:
#foreach(var Reason in ViewBag.ReasonsList)
{
<li>#Html.ActionLink("Edit", "Reasons", "Edit", new { id = Reason.Id }, null) #Reason.ReasonText</li>
<ul>
#foreach (var reasonlink in Reason.ReasonLinks)
{
<li>#reasonlink.URL</li>
}
</ul>
}
The Problem
This works fine, except for the edit link. While the values and code here appear to work directly (i.e the link is firing directly), RavenDB saves my document's ID as "reasons/1".
So, when the URL happens and it passes the ID, the resulting route is "http://localhost:4976/Reasons/Edit/reasons/2". So, the ID is appended correctly, but MVC is interpreting it as its own route.
Any suggestions on how I might be able to get around this? Do I need to create a special route to handle it or is there something else I can do?
I just downloaded the latest version of RavenDB and tried this out.
public class Entity {
public int Id { get;set; }
public string Text { get;set; }
}
When I saved it to RavenDB, the id in Raven was "entities/1", but the mapping in RavenDB client was able to successfully interpret the Id from what was in the database to the integer that I wanted.
var entity = session.Load<Entity>(1);
Assert.IsTrue(entity.Id == 1);
You do not need a extension method, and this way you would not need to alter any routes as mentioned above, because you will be dealing with good ol' integers. The string Ids were almost a deal breaker, but amazingly this works so RavenDB is back in the hunt.
Note: I figured this out from watching a Rob Ashton talk and realizing that all his document classes had integers as Ids.
I was having a similar issue and came up with my own solution before I found the link to Shiju Varghese blog post referenced by #jfar.
It might not be as clean and simple as the solutions provided in the blog post, but I do believe it can compete as a solution none the less. So here goes:
In a standard model class, when using RavenDB, we normally have an id property like so:
public string Id { get; set; }
What I did, was to add another id property like so:
public int? IdInt
{
get { return int.Parse(Id.Substring(Id.IndexOf("/") + 1)); }
}
This will give us the number part of the given RavenDB id.
I then had a class that looked something like this:
[Bind(Exclude = "IdInt")]
public class Item
{
public string Id { get; set; }
public int? IdInt
{
get { return int.Parse(Id.Substring(Id.IndexOf("/") + 1)); }
}
...
}
Note that I have excluded the IdInt property, as I don't want the model binder to handle it.
Furthermore, note, that the IdInt property is nullable. This is to avoid problems with the model binder later on, when we are creating new items and the Id property is null.
Then in the routes I declared a rule similar to this:
routes.MapRoute(
"WithParam", // Route name
"{controller}/{action}/{id}" // URL with parameters
);
Later on using an ActionLink or something similar we can do the following:
#Html.ActionLink("Details", "Details", new { id = item.IdInt })
And lastly when we press the rendered link, we are sent to the appropriate action which could look something like this:
public ActionResult Details(int id)
{
var item = _session.Load<Item>(id);
return View(item);
}
The reason why this will work is because of the Load method, which takes a ValueType as parameter and then automatically resolves the number to the correct RavenDB id.
What we have achieved with this approach is a url that looks something like this:
/items/details/1
As I said in the beginning, this solution is less elegant than the previous suggested solutions, however, this approach will give you a cleaner url as you can work with the id's as you normally would.
FYI, the link posted by #jfar was exactly the article. The following is the solution I used from the article:
Solution 2 - Modify ASP.NET MVC Route
Modify the ASP.NET MVC routes in the
Global.asax.cs file, as shown in the
following code:
routes.MapRoute(
"WithParam", // Route name
"{controller}/{action}/{*id}" // URL with parameters
);
We just put "*" in front of the id
variable that will be working with the
default Id separator of RavenDB