lucene search field contains space - search

Here is my Lucene.Net example`
using Lucene.Net.Analysis;
using Lucene.Net.Analysis.Standard;
using Lucene.Net.Documents;
using Lucene.Net.Index;
using Lucene.Net.QueryParsers;
using Lucene.Net.Search;
using Lucene.Net.Store;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Directory = Lucene.Net.Store.Directory;
using Version = Lucene.Net.Util.Version;
namespace LuceneTest
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello Lucene.net");
var Book1 = new Document();
Book1.Add(new Field("Id", "1", Field.Store.YES, Field.Index.NOT_ANALYZED));
Book1.Add(new Field("Author", "Tom and Jerry".ToLower(), Field.Store.YES, Field.Index.ANALYZED));
Book1.Add(new Field("Series", "Science".ToLower(), Field.Store.YES, Field.Index.NOT_ANALYZED));
Book1.Add(new Field("Location", "Melbourne", Field.Store.YES, Field.Index.NOT_ANALYZED));
var Book2 = new Document();
Book2.Add(new Field("Id", "2", Field.Store.YES, Field.Index.NOT_ANALYZED));
Book2.Add(new Field("Author", "Michael Jordan".ToLower(), Field.Store.YES, Field.Index.ANALYZED));
Book2.Add(new Field("Series", "Science and Fiction".ToLower(), Field.Store.YES, Field.Index.NOT_ANALYZED));
Book2.Add(new Field("Location", "Sydeny", Field.Store.YES, Field.Index.NOT_ANALYZED));
var Book3 = new Document();
Book3.Add(new Field("Id", "3", Field.Store.YES, Field.Index.NOT_ANALYZED));
Book3.Add(new Field("Author", "David Beckham".ToLower(), Field.Store.YES, Field.Index.ANALYZED));
Book3.Add(new Field("Series", "Math Science".ToLower(), Field.Store.YES, Field.Index.NOT_ANALYZED));
Book3.Add(new Field("Location", "London", Field.Store.YES, Field.Index.NOT_ANALYZED));
var Book4 = new Document();
Book4.Add(new Field("Id", "4", Field.Store.YES, Field.Index.NOT_ANALYZED));
Book4.Add(new Field("Author", "Michael David".ToLower(), Field.Store.YES, Field.Index.ANALYZED));
Book4.Add(new Field("Series", "Computer Science".ToLower(), Field.Store.YES, Field.Index.NOT_ANALYZED));
Book4.Add(new Field("Location", "New York", Field.Store.YES, Field.Index.NOT_ANALYZED));
var Book5 = new Document();
Book5.Add(new Field("Id", "5", Field.Store.YES, Field.Index.NOT_ANALYZED));
Book5.Add(new Field("Author", "Kobe Bryant".ToLower(), Field.Store.YES, Field.Index.ANALYZED));
Book5.Add(new Field("Series", "Computer".ToLower(), Field.Store.YES, Field.Index.NOT_ANALYZED));
Book5.Add(new Field("Location", "Los Angeles", Field.Store.YES, Field.Index.NOT_ANALYZED));
Directory directory = FSDirectory.Open(new DirectoryInfo(Environment.CurrentDirectory + "\\LuceneIndex"));
Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_30);
Analyzer analyzer2 = new KeywordAnalyzer();
var writer = new IndexWriter(directory, analyzer, true, IndexWriter.MaxFieldLength.LIMITED);
writer.AddDocument(Book1);
writer.AddDocument(Book2);
writer.AddDocument(Book3);
writer.AddDocument(Book4);
writer.AddDocument(Book5);
writer.Optimize();
writer.Dispose();
IndexReader indexReader = IndexReader.Open(directory, true);
Searcher seacher = new IndexSearcher(indexReader);
var queryParser = new QueryParser(Version.LUCENE_30, "Series", analyzer);
var query = queryParser.Parse("\"Computer Science\"");
Console.WriteLine("Searching For " + query);
TopDocs resultDocs = seacher.Search(query, indexReader.MaxDoc);
var hits = resultDocs.ScoreDocs;
foreach (var hit in hits)
{
var documentFromSearch = seacher.Doc(hit.Doc);
Console.WriteLine(documentFromSearch.Get("Id") + ", " + documentFromSearch.Get("Author") + ", " + documentFromSearch.Get("Location") + ", " + documentFromSearch.Get("Series"));
}
if (hits.Count() == 0)
Console.WriteLine("No result.");
Console.ReadKey();
}
}
}
Line 78,var query = queryParser.Parse("\"Computer Science\"");`
If I make the parameter "Computer Science", it will the book that series is "computer" or is "science".(record 1 and 5) What I want here is actually the record which has the series "Computer Science" (Book4). What should I change?
Thank you in advance

The common way of handling this issue is to use a phrase query in Lucene -- for example, in query syntax you could use "Computer Science" book4 to look for "book4" in Computer Science.

Related

Updated: Generating Envelope with eNotary Signature, Seal, DateSigned TABS thru eSign api

In our organization dmz web application, On behalf of Signer(our client) we generate envelopes and send it to notary. And we are trying to utilize the Signature, Seal, DateSigned TABS in eNotary (InPersonSigner Receipient) envelope thru eSign API in sandbox environment. But docusignapi is not allowing us to create Signature, Seal, DateSigned TABS, but it allows only Notarize TAB.
How we can utilize the Signature, Seal, DateSigned TABS for Notary thru eSign API?
Updated Code throws attached error "Notary_Signing_Host_Tabs_Not_Allowed":
string signerEmail = "signer#domain.com";
string signerName = "Signer";
string notaryEmail = "notary#domain.com";
string notaryName = "Notary";
// Step 1. Create the envelope definition
EnvelopeDefinition envelope = new EnvelopeDefinition();
envelope.EmailSubject = "Please sign this document";
byte[] buffer = System.IO.File.ReadAllBytes("Execute_and_Notarize.pdf");
Document doc1 = new Document();
String doc1b64 = Convert.ToBase64String(buffer);
doc1.DocumentBase64 = doc1b64;
doc1.Name = "Notarize1_1page"; // can be different from actual file name
doc1.FileExtension = "pdf";
doc1.DocumentId = "1";
// The order in the docs array determines the order in the envelope
envelope.Documents = new List<Document> { doc1 };
Notarize notarize1 = new Notarize
{
AnchorString = "/notary1/",
AnchorUnits = "pixels",
AnchorXOffset = "10",
AnchorYOffset = "10",
Required = "true"
};
SignHere notarizesignhere1 = new SignHere
{
AnchorString = "/notarysigner1/",
AnchorUnits = "pixels",
AnchorXOffset = "10",
AnchorYOffset = "10"
};
SignHere notarizesignhere2 = new SignHere
{
AnchorString = "/notarysignerseal1/",
AnchorUnits = "pixels",
AnchorXOffset = "10",
AnchorYOffset = "10",
IsSealSignTab = "true"
};
DateSigned notarizedatesigned1 = new DateSigned()
{
AnchorString = "/notarysigner1ds/",
AnchorUnits = "pixels",
AnchorXOffset = "10",
AnchorYOffset = "10"
};
Tabs notaryTabs = new Tabs
{
NotarizeTabs = new List<Notarize> { notarize1 },
SignHereTabs = new List<SignHere> { notarizesignhere1, notarizesignhere2 },
DateSignedTabs = new List<DateSigned> { notarizedatesigned1 }
};
NotaryHost notaryHost = new NotaryHost()
{
Email = notaryEmail,
Name = notaryName,
DeliveryMethod = "email",
RecipientId = "2",
Tabs = notaryTabs
};
// Create signHere fields (also known as tabs) on the documents,
// We're using anchor (autoPlace) positioning
//
// The DocuSign platform seaches throughout your envelope's
// documents for matching anchor strings.
SignHere signHere1 = new SignHere
{
AnchorString = "/signer1/",
AnchorUnits = "pixels",
AnchorXOffset = "10",
AnchorYOffset = "10"
};
DateSigned dateSigned1 = new DateSigned()
{
AnchorString = "/signer1ds/",
AnchorUnits = "pixels",
AnchorXOffset = "10",
AnchorYOffset = "10"
};
// Tabs are set per recipient / signer
Tabs signer1Tabs = new Tabs
{
SignHereTabs = new List<SignHere> { signHere1 },
DateSignedTabs = new List<DateSigned> { dateSigned1 }
};
// Create a signer recipient to sign the document, identified by name and email
// We set the clientUserId to enable embedded signing for the recipient
// We're setting the parameters via the object creation
InPersonSigner inPersonSigner1 = new InPersonSigner()
{
Email = signerEmail,
Name = signerName,
RecipientId = "1",
InPersonSigningType = "notary",
Tabs = signer1Tabs
};
inPersonSigner1.NotaryHost = notaryHost;
// Add the recipient to the envelope object
Recipients recipients = new Recipients
{
InPersonSigners = new List<InPersonSigner> { inPersonSigner1 },
};
envelope.Recipients = recipients;
Image Attachment: errorCode - notary_signing_host_tabs_not_allowed
You are missing one line at least:
inPersonSigner1.NotaryHost = notaryHost;
Here is a C# snippet taken from my blog post on the subject:
// To complete this code snippet, you will need an Envelope and a Document object
var notarizeTab = new Notarize
{
XPosition = "100",
YPosition = "100"
};
var signHereTab = new SignHere
{
XPosition = "200",
YPosition = "200"
};
var notarizeTabs = new List<Notarize>();
notarizeTabs.Add(notarizeTab);
var signHereTabs = new List<SignHere>();
signHereTabs.Add(signHereTab);
var notaryHost = new NotaryHost
{
Name = "Nadia Notary",
Email = "nadianotary#domain.com",
DeliveryMethod = "email",
RecipientId = "2",
Tabs = new Tabs { NotarizeTabs = notarizeTabs }
};
// InPersonSigner is used here even if the signer doesn't sign in person
var inPersonSigner = new InPersonSigner
{
NotaryHost = notaryHost,
Name = "Eddie End User",
Email = "endusersigner#domain.com",
RecipientId = "1",
InPersonSigningType = "notary",
Tabs = new Tabs { SignHereTabs = signHereTabs }
};
var inPersonSigners = new List<InPersonSigner>();
inPersonSigners.Add(inPersonSigner);
var recipients = new Recipients{ InPersonSigners = inPersonSigners };
You can add whatever tabs you need, but the important thing is to understand that the notary is a different recipient and they have their own separate tabs.

Insert data to fields in document inside template or load document from template into envelope

Looking for paths to try, drawing blanks.
Is there a way to either send a template (and all its document) field data or to send a document from a template inside a new envelope?
I've found ways to do this if the file is local, but I'm desperate to have this be something they can still admin from the template portal and I can just pass known data values.
Solved
...
ApiClient apiClient = new ApiClient(basePath);
apiClient.Configuration.AddDefaultHeader("Authorization", "Bearer " + accessToken);
EnvelopesApi envelopesApi = new EnvelopesApi(apiClient.Configuration);
EnvelopeDefinition envDef = new EnvelopeDefinition();
envDef.EmailSubject = "stack test";
envDef.TemplateId = mytemplateid
List<TemplateRole> templateRolesList = new List<TemplateRole>();
TemplateRole tRole = new TemplateRole();
Tabs tabs = new Tabs();
List<TemplateRole> rolesList = new List<TemplateRole>();
List<Text> textTabs = new List<Text>();
tRole.RoleName = "Sales Counselor";
Text texttab1 = new Text();
texttab1.TabLabel = "Buyer Name";
texttab1.Value = "name goes here";
Text texttab2 = new Text();
texttab2.TabLabel = "Elevation";
texttab2.Value = "AB";
textTabs.Add(texttab1);
textTabs.Add(texttab2);
tabs.TextTabs = textTabs;
tRole.Tabs = tabs;
tRole.Name="Sales Counselor";
tRole.Email="me#gmail.com";
templateRolesList.Add(tRole);
envDef.TemplateRoles = templateRolesList;
envDef.Status = "sent";
EnvelopeSummary results = envelopesApi.CreateEnvelope(accountId, envDef);
...

Executing a site workflow in sharepoint from a console application

I am trying to execute a site workflow from a console application.When the code to execute the workflow runs, it thows an error
An unhandled exception of type 'Microsoft.SharePoint.Client.ServerException' occurred in Microsoft.SharePoint.Client.Runtime.dll
Additional information:
Cannot invoke method or retrieve property from null object. Object returned by the following call stack is null. "GetWorkflowInteropService new Microsoft.SharePoint.WorkflowServices.WorkflowServicesManager()"
string userName = "username";
string password = "password";
string siteUrl = "https://share.example.com/sites/workflowsite";
string workflowName = "MyWorkflow";
using (ClientContext clientContext = new ClientContext(siteUrl))
{
SecureString securePassword = new SecureString();
foreach (char c in password.ToCharArray()) securePassword.AppendChar(c);
clientContext.Credentials = new NetworkCredential(userName, securePassword);
Web web = clientContext.Web;
WorkflowAssociationCollection wfAssociations = web.WorkflowAssociations;
WorkflowAssociation wfAssociation = wfAssociations.GetByName(workflowName);
clientContext.Load(wfAssociation);
clientContext.ExecuteQuery();
WorkflowServicesManager manager = new WorkflowServicesManager(clientContext, web);
InteropService workflowInteropService = manager.GetWorkflowInteropService();
clientContext.Load(workflowInteropService);
clientContext.ExecuteQuery();
workflowInteropService.StartWorkflow(wfAssociation.Name, new Guid(), Guid.Empty, Guid.Empty, null);
clientContext.ExecuteQuery(
}
The code below for your reference:
using Microsoft.SharePoint.Client;
using Microsoft.SharePoint.Client.WorkflowServices;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security;
using System.Text;
using System.Threading.Tasks;
namespace CSOMStartWorkflow {
class Program {
static void Main(string[] args) {
Console.WriteLine("Enter the Office 365 Login Name");
string loginId = Console.ReadLine();
string pwd = GetInput("Password", true);
Console.WriteLine("Web Url:");
string webUrl = Console.ReadLine();
Console.WriteLine("List Name:");
string listName = Console.ReadLine();
Console.WriteLine("Workflow Name");
string workflowName = Console.ReadLine();
var passWord = new SecureString();
foreach (char c in pwd.ToCharArray()) passWord.AppendChar(c);
using (var ctx = new ClientContext(webUrl)) {
ctx.Credentials = new SharePointOnlineCredentials(loginId, passWord);
var workflowServicesManager = new WorkflowServicesManager(ctx, ctx.Web);
var workflowInteropService = workflowServicesManager.GetWorkflowInteropService();
var workflowSubscriptionService = workflowServicesManager.GetWorkflowSubscriptionService();
var workflowDeploymentService = workflowServicesManager.GetWorkflowDeploymentService();
var workflowInstanceService = workflowServicesManager.GetWorkflowInstanceService();
var publishedWorkflowDefinitions = workflowDeploymentService.EnumerateDefinitions(true);
ctx.Load(publishedWorkflowDefinitions);
ctx.ExecuteQuery();
var def = from defs in publishedWorkflowDefinitions
where defs.DisplayName == workflowName
select defs;
WorkflowDefinition workflow = def.FirstOrDefault();
if(workflow != null) {
// get all workflow associations
var workflowAssociations = workflowSubscriptionService.EnumerateSubscriptionsByDefinition(workflow.Id);
ctx.Load(workflowAssociations);
ctx.ExecuteQuery();
// find the first association
var firstWorkflowAssociation = workflowAssociations.First();
// start the workflow
var startParameters = new Dictionary<string, object>();
if (ctx.Web.ListExists(listName)) {
List list = ctx.Web.GetListByTitle(listName);
CamlQuery query = CamlQuery.CreateAllItemsQuery();
ListItemCollection items = list.GetItems(query);
// Retrieve all items in the ListItemCollection from List.GetItems(Query).
ctx.Load(items);
ctx.ExecuteQuery();
foreach (ListItem listItem in items) {
Console.WriteLine("Starting workflow for item: " + listItem.Id);
workflowInstanceService.StartWorkflowOnListItem(firstWorkflowAssociation, listItem.Id, startParameters);
ctx.ExecuteQuery();
}
}
}
}
Console.WriteLine("Press any key to close....");
Console.ReadKey();
}
private static string GetInput(string label, bool isPassword) {
Console.ForegroundColor = ConsoleColor.White;
Console.Write("{0} : ", label);
Console.ForegroundColor = ConsoleColor.Gray;
string strPwd = "";
for (ConsoleKeyInfo keyInfo = Console.ReadKey(true); keyInfo.Key != ConsoleKey.Enter; keyInfo = Console.ReadKey(true)) {
if (keyInfo.Key == ConsoleKey.Backspace) {
if (strPwd.Length > 0) {
strPwd = strPwd.Remove(strPwd.Length - 1);
Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
Console.Write(" ");
Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
}
} else if (keyInfo.Key != ConsoleKey.Enter) {
if (isPassword) {
Console.Write("*");
} else {
Console.Write(keyInfo.KeyChar);
}
strPwd += keyInfo.KeyChar;
}
}
Console.WriteLine("");
return strPwd;
}
}
}
Reference: Starting a SharePoint Online Workflow with the Client Side Object Model (CSOM)

QueryExpression Phonecall to Contact

I've been stuck on this for a bit. Here's the scope of what I'm trying to do:
Retrieve phonecall records while bringing in contact information within the "to" field.
After much research, I have boiled down the code to below. I'm not too sure if I'm doing linked entities right - but can't determine how to do a nested join like I need to as I need to somehow get to the activitypointer -> activityparty -> contact...I just don't know where I"m going wrong. Any help would be greatly appreciated.
using Microsoft.Crm.Sdk.Messages.Samples;
using Microsoft.Xrm.Sdk.Query.Samples;
QueryExpression qExpression = new QueryExpression("phonecall")
{
ColumnSet = cs,
LinkEntities =
{
new LinkEntity()
{
EntityAlias = "ap",
LinkFromEntityName= "phonecall",
LinkFromAttributeName = "activityid",
LinkToEntityName = "activitypointer",
LinkToAttributeName = "activityid",
JoinOperator = JoinOperator.Inner
},
new LinkEntity()
{
EntityAlias = "app",
LinkFromEntityName= "activitypointer",
LinkFromAttributeName = "activityid",
LinkToEntityName = "activityparty",
LinkToAttributeName = "activityid",
JoinOperator = JoinOperator.Inner,
LinkCriteria = new FilterExpression
{
Conditions =
{
new ConditionExpression("ParticipationTypeMask", ConditionOperator.Equal, 2),
}
}
},
new LinkEntity()
{
EntityAlias = "con",
Columns = new ColumnSet("fullname","contactid"),
JoinOperator = JoinOperator.Inner,
LinkFromEntityName = "activityparty",
LinkFromAttributeName = "partyid",
LinkToEntityName = "contact",
LinkToAttributeName = "contactid"
}
}
};
Looks like I answered my own question, giving some inspiration. I had to nest the link within a link.
This is what works now
QueryExpression qExpression = new QueryExpression("phonecall")
{
ColumnSet = cs,
LinkEntities =
{
new LinkEntity()
{
EntityAlias = "app",
LinkFromEntityName= "phonecall",
LinkFromAttributeName = "activityid",
LinkToEntityName = "activityparty",
LinkToAttributeName = "activityid",
JoinOperator = JoinOperator.Inner,
LinkCriteria = new FilterExpression
{
Conditions =
{
new ConditionExpression("participationtypemask", ConditionOperator.Equal, 2),
}
},
LinkEntities =
{
new LinkEntity()
{
EntityAlias = "con",
Columns = new ColumnSet("fullname","contactid"),
JoinOperator = JoinOperator.Inner,
LinkFromEntityName = "activityparty",
LinkFromAttributeName = "partyid",
LinkToEntityName = "contact",
LinkToAttributeName = "contactid"
}
}
},
}
};
Using DLaB.Xrm, you could re-write this like this:
var qe = QueryExpressionFactory.Create(cs, "phonecall");
var activityParty = qe.AddLink("activityparty", "activityid");
activityParty.WhereEqual("participationtypemask", 2);
activityParty.AddLink("contact", "partyid", "contactid")
.AddColumns("fullname","contactid");
Having a lot less code to look at tends to make it easier to Grok IMHO.
This is how I would read teach line of my 5 lines listed:
I'm doing a Query against the Phone Call Entity
Joining to the Activity Party on the activity Id (same key for both, no need to duplicate)
Where the activityParty's ParticipationTypeMask == 2
And joining from that to the Contact on ActivityParty.PartyId == Contact.ContactId
Including the name and Id of the contact.

populate list with for loop viewmodel

Just wondering if anyone can help with this problem. I have a viewmodel which populates a dropdownlist. I was just wondering if it's possible to change my code below so that I can use a for loop to populate the list.
ViewModel
public IEnumerable<SelectListItem> numberOfAdults { get; set; }
Controller
numberOfAdults = new[]
{
new SelectListItem {Value = "1", Text = "1"},
new SelectListItem {Value = "2", Text = "2"},
new SelectListItem {Value = "3", Text = "3"},
new SelectListItem {Value = "4", Text = "4"},
new SelectListItem {Value = "5", Text = "5"},
new SelectListItem {Value = "6", Text = "6"},
new SelectListItem {Value = "7", Text = "7"},
new SelectListItem {Value = "8", Text = "8"},
new SelectListItem {Value = "9", Text = "9"},
new SelectListItem {Value = "10", Text = "10"}
}
View
#Html.DropDownListFor(x => x.selectedAdultValue, new SelectList(Model.numberOfAdults, "Value", "Text"), null, new {#id="NumerOfAdults" })
Something like the following is what I would like, but not sure where to put it in model or controller.
for(int i = 0; i < 10; i++)
{
i;
}
It could be as simple as:
numberOfAdults = Enumerable.Range(1, 10).Select(x => new SelectListItem
{
Value = x.ToString(),
Text = x.ToString()
});
or if you really want to use a for loop (I don't see why would you want that but anyway):
var result = new List<SelectListItem>();
for(int i = 1; i <= 10; i++)
{
result.Add(new SelectListItem {
Value = x.ToString(),
Text = x.ToString()
});
}
numberOfAdults = result.ToArray();

Resources