Solr index directory of files add file permissions from database - wordpress

I'm using Solr to index a directory of pdf and word files. I want Solr to search these files but only return results based off a logged in user's permissions. Is it possible to index a directory of files as well as query a database containing the file permissions and add the data to the index as a xml entity and perform a filtered query on those results?
I am using WordPress as the CMS system with a file management plugin called Filebase. Filebase syncs with a directory to upload documents to the site. I have Solr configured to index the filebase directory containing the documents. Filebase has permissions that I set on each file.
My thought is if I can store the file's minimum user level position integer in the index I can then perform a filtered query to only display results with a user level of 'x'.
I hope this makes sense.

Yes, if you are on Solr 4+, you can push a Partial Update to Solr index.
SCHEMA
For partial update, all fields in your schema.xml need to be stored.
This is how your fields section should look like in schema.xml:
<fields>
<field name="id" type="string" indexed="true" stored="true" required="true" />
<field name="title" type="text_general" indexed="true" stored="true"/>
<field name="description" type="text_general" indexed="true" stored="true" />
<field name="body" type="text_general" indexed="true" stored="true"/>
<field name="permission" type="integer" indexed="true" stored="true" />
</fields>
INDEXING:
You can first index all documents(directory of pdf and word) to your index.
Then you can send a partial update to the permission field for a particular id.
When you send partial update, what actually happens in background is:
Solr will go and fetch values for all other fields for that document, such as title, description, body
Delete old document
Push new updated document to Solr index, with all existing fields as well as new permission field
Suppose you want to set permission=5 for document with id=document_1, your query should look like:
localhost:8080/solr/update?commit=true' -H 'Content-type:application/json' -d '[{"id":"document_1","permission":{"set":5}}]
Here is a good documentation on partial updates: http://solr.pl/en/2012/07/09/solr-4-0-partial-documents-update/

Related

Firestore - How to get ID of a Document from Collection? Android Java

I have a firestore collections "Usuarios", in this collections have a lot Documents, each Documents is a one user from my app, i need add more fields on the specific document, but, the Id of document is different that my (CurrentUser.getUUid());.
See here:
What I need is to write several more fields (dynamically) to a logged in user document, but currentUser.getUid returns a document field, not the document ID itself. Que seria o necessário para gravar naquele documento.
My solution was use other method to add documents to collection and the uuid from getCurrent user is already the id of document, i do not know if it is correct (for security), but, was my solution...

How to structure sub node of collections in Firestore?

I'm trying to migrate the following structure from real time database to Firestore :
• Resources
o SENT
 resId1
• name : xxxx
• url : xxx
 resI2
• name ……
o ACCEPT
 resId3
 etc……
o REFUSED
 restIdn
 etc….
So under root Node" Resources" I have some sub nodes (SENT, ACCEPT, REFUSED, ...) that contain List of resources items.
With Firestore it seems I can't have subCollection directly under collection (When I try to reproduce this structure with Firestore in the admin console I need to create an intermediate document like:
Collection --> document --> SubCollection --> documents
Witch lead to that structure:
Resources --> SENT --> SENT --> resId1 {name: xxx, url: yyyy}
So the sub node "SENT" is duplicated twice (one for the document and one for the sub collection).
This is not an improvement or a simplification at all, if I compare with firebase real time database.
Do I miss something? What is the best way for such kind of database structure?
(Edited 10/13/2017 # 11am)
It seems that there are two structures that will work for you.
Option 1: Three Root Collections
Create three collections at the root of your Firestore database
resources-sent
resources-accept
resources-refused
Each one contains documents.
Option 2: One Root Collection
Firestore allows for compound queries, so you could just make one collection at the root called resources and add a type parameter to each document where type is one of [sent, accept, refused].
Then you can do queries like this:
// Get all sent resources
db.collection("resources").where("type", "==", "sent").get()
Because of Firestore's built in indexes this query will always be fast!'
Option 3: Subcollections.
Create a root collection called resources containing only three docs:
sent
accept
refused
For each of these docs create a resources subcollection.
So to get all sent resources:
// Get all sent resources
db.collection("resources").doc("sent").collection("resources").get()

configure the order of constraint execution on a field in hibernate with xml file

`this is my sample.xml files
<field name="userName">
<constraint annotation="org.hibernate.validator.constraints.NotBlank"/>
<constraint annotation="javax.validation.constraints.Size">
<element name ="min">1</element>
<element name ="max">20</element>
</constraint>
</field>`
if there is a way to configure the hibernate validator so that "Size" validations runs only if the NotBlank valditons falis and show validations messages only for the Size not correct.
here is the modifed xml
<bean class="User">
<field name="systemCode">
<constraint annotation="org.hibernate.validator.constraints.NotBlank">
<groups>
<value>UserNameNotBlank</value>
</groups>
</constraint>
<constraint annotation="javax.validation.constraints.Size">
<groups>
<value>UserNameSize</value>
</groups>
<element name="min">1</element>
<element name="max">4</element>
</constraint>
</field>
</bean>
what are the next steps the interfaces had been created is it possible to performing ordering on the field level or is it possible only on method level.
Note : please give the reference link where xml based configurations are there.
There is no order for constraint validation unless a group sequence is used. The spec says:
By default, constraints are evaluated in no particular order
regardless of which groups they belong to...
And a little further on
To implement such ordering, a group can be defined as a sequence of
other groups...
See also http://beanvalidation.org/1.1/spec/#constraintdeclarationvalidationprocess-groupsequence-groupsequence

Determine corresponding field names of items in Request.Files?

Given a set of uploaded files in Request.Files, how do figure out which form field yielded which file?
I have a generic form emailer that various forms post to. This file generates an email of the name/value pairs contained in the form post. I'm trying to add support for uploaded files such that the table of name/value pairs will show the name of the file upload element and the name that the file was saved as.
However, I can't figure out how to link that information together. HttpPostedFile doesn't contain any information about the HTTP request (like which field name was used), and Request.Form doesn't contain any entries for uploaded files.
So while I can easily upload the files, I don't have an easy way to generate an email saying "this uploaded file was for this field, and this uploaded file was for that field".
Request.Files.Keys is a collection of field names corresponding to each uploaded file.

Using ASP.NET SQL Membership Provider, how do I store my own per-user data?

I'm using the ASP.NET SQL Membership Provider. So, there's an aspnet_Users table that has details of each of my users. (Actually, the aspnet_Membership table seems to contain most of the actual data).
I now want to store some per-user information in my database, so I thought I'd just create a new table with a UserId (GUID) column and an FK relationship to aspnet_Users. However, I then discovered that I can't easily get access to the UserId since it's not exposed via the membership API. (I know I can access it via the ProviderUserKey, but it seems like the API is abstracting away the internal UserID in favor of the UserName, and I don't want to go too far against the grain).
So, I thought I should instead put a LoweredUserName column in my table, and create an FK relationship to aspnet_Users using that. Bzzzt. Wrong again, because while there is a unique index in aspnet_Users that includes the LoweredUserName, it also includes the ApplicationId - so in order to create my FK relationship, I'd need to have an ApplicationId column in my table too.
At first I thought: fine, I'm only dealing with a single application, so I'll just add such a column and give it a default value. Then I realised that the ApplicationId is a GUID, so it'd be a pain to do this. Not hard exactly, but until I roll out my DB I can't predict what the GUID is going to be.
I feel like I'm missing something, or going about things the wrong way. What am I supposed to do?
I think you are looking for the ProfileProvider which let's you associate any arbitrary information you wish with the user.
ASP.NET Profile Properties Overview
ADDITION If the built-in ProfileProvider will not suit your needs, then you might consider implementing your own ProfileProvider by writing a class that derives from System.Web.Profile.ProfileProvider. This would enable you to write something that avoids the serialization issues you mentioned in your comment.
Implementing a Profile Provider
ADDITION Note about the SqlMembershipProvider. You are indeed correct that the Membership classes are really keyed on username even though the schema is keyed on UserId. This is frankly one of my pet peeves about the SqlMembershipProvider classes. This actually creates problem in a multi-application environment where you want a single user store but independent application role lists.
My recommendation would be to key on UserId since it is, as you mentioned, the primary key of the aspnet_Users table and is used in all the foreign key relationships and it is a single value. If you key on LowerUsername (and ApplicationId), and the username changes, you'll need to have cascade update enabled so that the change ripples to your custom tables.
To do this, you can implement a profile provider. Its not very difficult. You will basically set up your user specific settings like this:
(web.config):
<profile enabled="true" defaultProvider="MyProvider">
<providers>
<add name="MyProvider" connectionStringName="MembershipCnnStr" applicationName="MyApp" type="System.Web.Profile.SqlProfileProvider"/>
</providers>
<properties>
<add name="EmployeeId" type="String" />
<group name="UserSettings">
<add name="IsSandboxMode" type="Boolean" defaultValue="false" />
<add name="Shortcuts" type="System.Collections.Generic.List`1[System.string]" />
</group>
</properties>
</profile>
If you're looking at adding simple data tied to your users, such as added profile properties, you should look into Personalization.
Example, if you want to store a person's mother's maiden name as a part of their profile information you can do so using this feature.
It probably isn't the right choice for complex data, but it's a start.
Write .cs file like
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
FirstNameTextBox.Text = Server.HtmlDecode(Profile.FirstName);
LastNameTextBox.Text = Server.HtmlDecode(Profile.LastName);
}
}
and web.config
<profile>
<providers>
<add name="FirstName" type="System.String"/>
<add name="LastName" type="System.String"/>
<add name="MemberId" defaultValue="0" type="System.Int32"/>
<clear/>
<add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/"/>
</providers>
</profile>

Resources