{"id":330,"date":"2015-02-10T21:30:35","date_gmt":"2015-02-10T20:30:35","guid":{"rendered":"http:\/\/www.cymbeline.ch\/?p=330"},"modified":"2015-02-10T22:01:33","modified_gmt":"2015-02-10T21:01:33","slug":"linq-lucene-net-objectmapping","status":"publish","type":"post","link":"https:\/\/cymbeline.ch\/2015\/02\/10\/linq-lucene-net-objectmapping\/","title":{"rendered":"LINQ with Lucene.Net.ObjectMapping"},"content":{"rendered":"

Last time I mentioned that I started to work on supporting LINQ with Lucene.Net.ObjectMapping. That includes LINQ queries like the following:<\/p>\n

\r\nusing (Searcher searcher = new IndexSearcher(directory))\r\n{\r\n    IQueryable<BlogPost> posts =\r\n        from post in searcher.AsQueryable<BlogPost>()\r\n        where obj.Tag == "lucene"\r\n        orderby obj.Timestamp descending\r\n        select post;\r\n}\r\n<\/pre>\n

Now granted, the above example is a very basic one. So here’s a short list of other methods on IQueryable<T> that are already supported at this point: Any *<\/sup>, Count *<\/sup>, First *<\/sup>, FirstOrDefault *<\/sup>, OrderBy, OrderByDescending, Single *<\/sup>, SingleOrDefault *<\/sup>, Skip, Take, ThenBy, ThenByDescending, and finally Where.<\/p>\n

*<\/sup> Method is supported both with and without a filter predicate.<\/p>\n

With this, it becomes easy to build paging based on objects you get back as a result of a query on Lucene.Net. I’m still working on improving the supported filter expressions (most of all for Where, but all the other filterable methods naturally profit too). For instance, with the default JSON-based object mapping it is already possible to search for entries in a dictionary that maps a string to another property or object. Say you have a set of classes, defined as follows.<\/p>\n

\r\npublic class MyClass\r\n{\r\n    public int Id { get; set; }\r\n    public Dictionary<string, MyOtherClass> Map { get; set; }\r\n}\r\n\r\npublic class MyOtherClass\r\n{\r\n    public string Text { get; set; }\r\n    public int Sequence { get; set; }\r\n    public DateTime Timestamp { get; set; }\r\n}\r\n<\/pre>\n

Now you can actually search for instances of MyClass that satisfy certain conditions in the Map<\/em> dictionary, like this:<\/p>\n

\r\nvar query = from c in searcher.AsQueryable<MyClass>()\r\n            where c.Map["MyKey"].Sequence == 123\r\n            select c;\r\n<\/pre>\n

Since the items in the dictionary are mapped to analyzed fields in the Lucene.Net document, we can search on them!<\/p>\n

Delete and Update By Query<\/h2>\n

Now since I have this query expression binder to create Lucene.Net queries based on LINQ filter expressions, I’ve added an extension method to update and one to delete documents that match a query. So it is now possible to do this:<\/p>\n

\r\nindexWriter.Delete<MyClass>(x => x.Id == 1234);\r\nindexWriter.Update(myObject, x => x.Id == myObject.Id);\r\n<\/pre>\n

Call to Action<\/h2>\n

Now with all this said, I’m looking for volunteers to help me get more coverage on the LINQ queries, because that’s definitely where the weak spot is right now. If you’re interested, leave a comment here or on GitHub<\/a>.<\/p>\n

<\/p>","protected":false},"excerpt":{"rendered":"

Last time I mentioned that I started to work on supporting LINQ with Lucene.Net.ObjectMapping. That includes LINQ queries like the following: Now granted, the above example is a very basic one. So here’s a short list of other methods on IQueryable<T> that are already supported at this point: Any *, Count *, First *, FirstOrDefault … Continue reading “LINQ with Lucene.Net.ObjectMapping”<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[61],"tags":[17,12,80,77,78,79],"yoast_head":"\nLINQ with Lucene.Net.ObjectMapping - Tales of a Code Monkey<\/title>\n<meta name=\"description\" content=\"LINQ with Lucene.Net.ObjectMapping -- Outlook on LINQ support through Lucene.Net.ObjectMapping.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/cymbeline.ch\/2015\/02\/10\/linq-lucene-net-objectmapping\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"LINQ with Lucene.Net.ObjectMapping - Tales of a Code Monkey\" \/>\n<meta property=\"og:description\" content=\"LINQ with Lucene.Net.ObjectMapping -- Outlook on LINQ support through Lucene.Net.ObjectMapping.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cymbeline.ch\/2015\/02\/10\/linq-lucene-net-objectmapping\/\" \/>\n<meta property=\"og:site_name\" content=\"Tales of a Code Monkey\" \/>\n<meta property=\"article:published_time\" content=\"2015-02-10T20:30:35+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2015-02-10T21:01:33+00:00\" \/>\n<meta name=\"author\" content=\"roger\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"roger\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"2 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cymbeline.ch\/2015\/02\/10\/linq-lucene-net-objectmapping\/\",\"url\":\"https:\/\/cymbeline.ch\/2015\/02\/10\/linq-lucene-net-objectmapping\/\",\"name\":\"LINQ with Lucene.Net.ObjectMapping - Tales of a Code Monkey\",\"isPartOf\":{\"@id\":\"https:\/\/cymbeline.ch\/#website\"},\"datePublished\":\"2015-02-10T20:30:35+00:00\",\"dateModified\":\"2015-02-10T21:01:33+00:00\",\"author\":{\"@id\":\"https:\/\/cymbeline.ch\/#\/schema\/person\/cf1f3b3205f4266bf8b68a80fa6b0916\"},\"description\":\"LINQ with Lucene.Net.ObjectMapping -- Outlook on LINQ support through Lucene.Net.ObjectMapping.\",\"breadcrumb\":{\"@id\":\"https:\/\/cymbeline.ch\/2015\/02\/10\/linq-lucene-net-objectmapping\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cymbeline.ch\/2015\/02\/10\/linq-lucene-net-objectmapping\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cymbeline.ch\/2015\/02\/10\/linq-lucene-net-objectmapping\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cymbeline.ch\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"LINQ with Lucene.Net.ObjectMapping\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/cymbeline.ch\/#website\",\"url\":\"https:\/\/cymbeline.ch\/\",\"name\":\"Tales of a Code Monkey\",\"description\":\"... the adventures of a guy making software.\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/cymbeline.ch\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/cymbeline.ch\/#\/schema\/person\/cf1f3b3205f4266bf8b68a80fa6b0916\",\"name\":\"roger\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cymbeline.ch\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/33cc08db99ae52beb26ab6fda46e0eb7?s=96&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/33cc08db99ae52beb26ab6fda46e0eb7?s=96&r=g\",\"caption\":\"roger\"},\"sameAs\":[\"https:\/\/www.cymbeline.ch\"],\"url\":\"https:\/\/cymbeline.ch\/author\/roger\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"LINQ with Lucene.Net.ObjectMapping - Tales of a Code Monkey","description":"LINQ with Lucene.Net.ObjectMapping -- Outlook on LINQ support through Lucene.Net.ObjectMapping.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/cymbeline.ch\/2015\/02\/10\/linq-lucene-net-objectmapping\/","og_locale":"en_US","og_type":"article","og_title":"LINQ with Lucene.Net.ObjectMapping - Tales of a Code Monkey","og_description":"LINQ with Lucene.Net.ObjectMapping -- Outlook on LINQ support through Lucene.Net.ObjectMapping.","og_url":"https:\/\/cymbeline.ch\/2015\/02\/10\/linq-lucene-net-objectmapping\/","og_site_name":"Tales of a Code Monkey","article_published_time":"2015-02-10T20:30:35+00:00","article_modified_time":"2015-02-10T21:01:33+00:00","author":"roger","twitter_misc":{"Written by":"roger","Est. reading time":"2 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/cymbeline.ch\/2015\/02\/10\/linq-lucene-net-objectmapping\/","url":"https:\/\/cymbeline.ch\/2015\/02\/10\/linq-lucene-net-objectmapping\/","name":"LINQ with Lucene.Net.ObjectMapping - Tales of a Code Monkey","isPartOf":{"@id":"https:\/\/cymbeline.ch\/#website"},"datePublished":"2015-02-10T20:30:35+00:00","dateModified":"2015-02-10T21:01:33+00:00","author":{"@id":"https:\/\/cymbeline.ch\/#\/schema\/person\/cf1f3b3205f4266bf8b68a80fa6b0916"},"description":"LINQ with Lucene.Net.ObjectMapping -- Outlook on LINQ support through Lucene.Net.ObjectMapping.","breadcrumb":{"@id":"https:\/\/cymbeline.ch\/2015\/02\/10\/linq-lucene-net-objectmapping\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cymbeline.ch\/2015\/02\/10\/linq-lucene-net-objectmapping\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/cymbeline.ch\/2015\/02\/10\/linq-lucene-net-objectmapping\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cymbeline.ch\/"},{"@type":"ListItem","position":2,"name":"LINQ with Lucene.Net.ObjectMapping"}]},{"@type":"WebSite","@id":"https:\/\/cymbeline.ch\/#website","url":"https:\/\/cymbeline.ch\/","name":"Tales of a Code Monkey","description":"... the adventures of a guy making software.","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/cymbeline.ch\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/cymbeline.ch\/#\/schema\/person\/cf1f3b3205f4266bf8b68a80fa6b0916","name":"roger","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cymbeline.ch\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/33cc08db99ae52beb26ab6fda46e0eb7?s=96&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/33cc08db99ae52beb26ab6fda46e0eb7?s=96&r=g","caption":"roger"},"sameAs":["https:\/\/www.cymbeline.ch"],"url":"https:\/\/cymbeline.ch\/author\/roger\/"}]}},"_links":{"self":[{"href":"https:\/\/cymbeline.ch\/wp-json\/wp\/v2\/posts\/330"}],"collection":[{"href":"https:\/\/cymbeline.ch\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cymbeline.ch\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cymbeline.ch\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/cymbeline.ch\/wp-json\/wp\/v2\/comments?post=330"}],"version-history":[{"count":15,"href":"https:\/\/cymbeline.ch\/wp-json\/wp\/v2\/posts\/330\/revisions"}],"predecessor-version":[{"id":348,"href":"https:\/\/cymbeline.ch\/wp-json\/wp\/v2\/posts\/330\/revisions\/348"}],"wp:attachment":[{"href":"https:\/\/cymbeline.ch\/wp-json\/wp\/v2\/media?parent=330"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cymbeline.ch\/wp-json\/wp\/v2\/categories?post=330"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cymbeline.ch\/wp-json\/wp\/v2\/tags?post=330"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}