We're trying to add search functionality to our application. The search will be over customer data in a multi-tenant application. We need to be careful to make search people can't see or search for other people's data.
Spring Roo allows you to have an entity be searchable. Is there a way to limit the scope of the results to a particular customer id/name?
The project lead asked specifically if there was a way to divide it so each customer had their own index (segment?) in Solr. Has anyone tried this?
Thank you!
As long as you're not giving users unfettered access to the solr interface, I would think that a simple fq (filter query) would work. You would do something like &fq=customerid:1234.
Alternatively, if you need actual separation between the indexes, you can use solr cores, but these have to be configured independently.
Related
I am new to spring framework recent i have made small project on microservices, where i create two microservices
department service
User service
I need to know how can i use join in them, i have create one common field in both the service i.e departmentId,
when i use getmapping in user service containing department id fetching the data from department service in respective to that departmentId.
Using intellij, mongodb as database, spring framework,java
Since mongo is a document store type database.
It depends on how the data will be used. You'll need to think how the data will be queried, what will the response may be.
In a RDBMS, it is natural to denormalize your data and split it over several tables and use joins to create the views you need.
In a document store you do exactly the opposite you'll normalize your data and try to include as much as you can to satisfy most queries in one query.
When you use spring, you might also like to use https://spring.io/projects/spring-data-mongodb
If you want to gain in-depth knowledge on mongo, they have several courses available where they can teach you for free: https://university.mongodb.com/
I am trying to build a java based web application using Spring Boot and REST architecture using Spring MVC for the following purpose:
Search car parts through multiple set of criteria.
I try to explain it in different scenarios:
find part A of Brand B for Make C of Model D of year x.
find out what parts are available of Brand B for Make C of Model D of Year x.
Search multiple items at once for Vehicle C of Model D of Year x. For example if an engine is damaged and I want to quickly find out whether I have the parts (like pistons, cylinders, gaskets, etc.) in the supply. The result of this search is a list of the parts with their brands and prices.
My primary concern at this moment are the following two questions:
How should I model the data so that the search scenarios are achieved efficiently? What I mean is that how the relation between the entities in the Java and the persistence system should look like?
What kind of database should I use? SQL or NoSQL?
All the REST end-points will return Json objects.
I will be using Angular with Bootstrap for the front-end
Isn't this scenario a typical "faceted search"? I think that any solution designed to implement faceted search should work fine. For example Solr or Elasticsearch.
The advantage of the "faceted search" for the end users is the option to refine the search. Users can start with a broad search and the system will provide refining filter criteria, based on the current search results.
Today, all the major e-commerce sites have a kind of faceted search and every search engine support this type of browsing.
It seems to me that engines like Solr and Elasticsearch are the more natural solution, but even a standard RDBMS like Oracle has support for faceted search.
Faceted search in Solr
Filters vs. Facets: Definitions
I would put the focus on modelling it cleanly rather than efficiently - unless you already know that you will have a massive amount of data. Having it structured cleanly will make it easy to optimise if that is required later.
Normalise your data - there will be plenty of information out there on how to do this. The car industry is becoming more consolidated so many parts are now shared across different models and even different brands.
An ORM like hibernate can be used to map your entities to your tables. Spring provides extra support in this area which you might consider as you are already plan on using Spring MVC.
We have a Java web app with a hibernate backend that provides REST resources. Now we're facing the task to implement a generic search that is controlled by the query parameters in our get request:
some/rest/resource?name_like=foo&created_on>=2012-09-12&sort_by_asc=something
or similar.
We don't want to predefine all possible parameters(name, created_on,
something)
We don't want to have to analyze the request String to pick up control characters (like >=)
nor do we don't want to implement our own grammar to reflect things like _eq _like _goe and so on (as an alternative or addition to control characters)
Is there some kind of framework that provides help with this mapping from GET request parameters to database query?
Since we know which REST resource we're GETing we have the entity / table (select). It probably will also be necessary to predefine the JOINs that will be executed in order to limit the depths of a search.
But other than that we want the REST consuming client to be able to execute any search without us having to predefine how a certain parameter and a certain control sequence will get translated into a search.
Right now I'm trying some semi automatic solution building on Mysemas QueryDSL. It allows me to predefine the where columns and sort columns and I'm working on a simple string comparison to detect things like '_like', '_loe', ... in a parameter and then activate the corresponding predefined part of the search. Not much different from an SQL String except that it's SQL injection proof an type save.
However I still have to tell my search object that it should be able to potentially handle a query "look for a person with name like '???'". Right now this is okay as we only consume the REST resource internally and isolate the actual search creation quite well. If we need to make a search do more we can just add more predefinitions for now. But should we make our REST resources public at some time in the future that won't be so great.
So we're wondering, there has to be some framework or best practice or recommended solution to approaching this. We're not the first who want this. Redmine for example offers all of its resource via a REST interface and I can query at will. Or facebook with its Graph API. I'm sure those guys didn't just predefine all possibilities but rather created some generic grammar. We'd like to save as much as possible on that effort and use available solutions instead.
Like I said, we're using Hibernate so an SQL or HQL solution would be fine or anything that builds on entities like QueryDsl. (Also there's the security issue concerning SQL injection)
Any suggestions? Ideas? Will we just have to do it all ourselves?
From a .NET perspective the closest thing I can think of would be a WCF data service.
Take a look at the uri-conventions specified on the OData website. There is some good information on the section on 4.5 Filter System Query Option. You'll notice that a lot of the examples on this site are .NET related, but there are other suggestions for getting this to work with Java.
Kind of a higher level question here.I've got a web application that is fairly simple. There are three seperate "objects" in the application. A Filter, an Authorization, and a Job. Each Job has to have a Filter and an Authorization to run.
Now a user of this application can create any of these objects and they are all linked to that specific user. Now however, the requirements state that they'd like to implement sharing. So a user can share their created items with other users. Honestly I'm just not sure of the best method to implement such a feature and am hoping someone can provide some ideas.
In the DB, each record has a user column that identifies the user who created it. I initially thought of adding a shareUser column, but that wouldn't really work since each record could be shared with multiple users. I'm just not sure the best way to tie these all together. Do I need an entirely new table in the DB that link's users to shared records?
Any thoughts on this would be appreciated. Thank you.
Yes, you do need a new table for each type of record you need to be "owned". You should use cross reference tables for this case.
something like:
userFilter
- userId
- filterId
If a user can only share a record they exist, you should have a createdByUserId column on the particular table.
This task occurs from time to time in my projects. I need to handle a collection of some complex elements, having different attributes, such as login, password_hash, role, etc. And, I need to be able to query that collection, just like I query a table in the database, having only partial data. For example: get all users, with role "user". Or check, if there's a user with login "root" and role "superuser". Removing items, based on same data is also needed. The first attempt I've tried is to use Google collections, Apache collections, and lambdaj. All of them have very similar preicate mechanism, but with a great disadvantage: it is based on iteration, one by one, over the collection of items, which is not good, for often used collections, containing big amounts of data. Could you please suggest me some solution? Thanks.
UPDATE:
Currently I've solved this problem by implementing my custom collection, with multiple indexes , so that I can perform direct queries: http://code.google.com/p/tablej/
The database isn't automagically efficient either; you actually need to configure a database (by putting indices on relevant columns) for it to be able to do searches efficiently.
In a similar way you can optimize your code for speed. If you need to do a lot of lookups based on a few criteria you could make dedicated collections for that. Similar to an index on a database.
You'd do that by not only inserting your User into a Users list, but by putting that same user in for instance a Map keyed on Role:
public void addUser(User user) {
users.add(user);
// your index
if (!usersByRole.containsKey(user.getRole()) {
usersByRole.put(user.getRole(), new ArrayList<User>());
}
usersByRole.get(user.getRole()).add(user);
}
public List<User> findByRole(String role) {
if (!usersByRole.containsKey(role)) {
return Collectsions.emptyList();
}
return Collections.unmodifieableList(usersByRole.get(role));
}
Java can't do LINQ. It doesn't even come close, due to the lack of lambdas, yield, extension methods and expression trees. The quaere project offers a poor-man's substitute.
I don't think this will satisfy your algorithmic efficiency requirements, however. These can only be done in one of two ways, AFAIK:
Hand-coded data structures, optimised for the questions you want to ask.
In-memory HSQLDB.
The former is hard, but likely to yield the best performance. The latter won't be as fast, but it will be OK, especially if properly tuned with indexes, and much simpler to work with.
You could embed a database into your app.
Here is a discussion on selecting the best embedded Java database.
The ones below are probably the top three (They are all free).
HSQLDB has a good reputation.
Java DB Java DB is included in
the Java SE Development Kit, and is
the developer database for the Sun
GlassFish Enterprise Server. It also
has a good reputation.
Berkeley DB Is a mature product, also high reputation.