UWInfo Blog
發表新文章
[Join] | [忘記密碼] | [Login]
搜尋

搜尋意見
文章分類-#Author#
[所有文章分類]
所有文章分類
  • ASP.NET (48)
  • ASP.NET2.0 (15)
  • ASP.NET4.0 (34)
  • JavaScript (49)
  • jQuery (26)
  • FireFox (4)
  • UW系統設定 (3)
  • SQL (39)
  • SQL 2008 (25)
  • mirror (4)
  • SVN (4)
  • IE (9)
  • IIS (20)
  • IIS6 (1)
  • 閒聊 (7)
  • W3C (6)
  • 作業系統 (9)
  • C# (24)
  • CSS (12)
  • FileServer (1)
  • HTML 5 (11)
  • CKEditor (3)
  • UW.dll (13)
  • Visual Studio (16)
  • Browser (8)
  • SEO (1)
  • Google Apps (3)
  • 網站輔助系統 (4)
  • DNS (5)
  • SMTP (4)
  • 網管 (11)
  • 社群API (3)
  • SSL (4)
  • App_Inventor (1)
  • URLRewrite (2)
  • 開發工具 (6)
  • JSON (1)
  • Excel2007 (1)
  • 試題 (3)
  • LINQ (1)
  • bootstrap (0)
  • Vue (3)
  • IIS7 (3)
  • foodpanda (2)
  • 編碼 (2)
  • 資安 (3)
  • Sourcetree (1)
  • MAUI (1)
  • CMD (1)
  • my sql (1)
最新回應
  • Newtonsoft.Json.JsonConvert.DeserializeObject 失敗的情況
    test...more
  • dotnet ef dbcontext scaffold
    ...more
  • [ASP.NET] 利用 aspnet_regiis 加密 web.config
    ...more
  • IIS ARR (reverse proxy) 服務安裝
    ...more
  • [錯誤訊息] 請加入 ScriptResourceMapping 命名的 jquery (區分大小寫)
    ...more
  • 用 Javascript 跨網頁讀取 cookie (Cookie cross page, path of cookie)
    ...more
  • 線上客服 - MSN
    本人信箱被盜用以致資料外洩,是否可以請貴平台予以協助刪除該信箱之使用謝謝囉...more
  • 插入文字到游標或選取處
    aaaaa...more
  • IIS 配合 AD (Active Directory) 認証, 使用 .Net 6.0
    太感謝你了~~~你救了我被windows 認證卡了好幾天QQ...more
  • PostgreSQL 的 monitor trigger
    FOR EACH ROW 可能要改為 FOR EACH STATEMENT ...more
標籤
  • web test
  • 欄位
  • ip
  • 5986
  • [U2]
  • CK
  • line pay p
  • SU
  • openExtern
  • SQL
  • web.
  • -3089
  • 22
  • 考試
  • Needs Lock
  • 8
  • UW
  • C#
  • IE11
  • aspnet ORD
  • 100
  • IIS7
  • 916
  • c
  • Find
  • -9692
  • load
  • 56
  • 34
  • 權限
  • json
  • for
  • 1124
  • 380
  • Ubuntu
  • C212112112
  • aspjpeg
  • ad
  • [t]
  • User
  • nsftw
  • query
  • Chrome
  • 878
  • 1
  • Image
  • orm
  • sw
  • UWInfo
  • Doug
頁數 2 / 4 上一頁 下一頁
搜尋 欄位 結果:
使用Lucene.Net達成全文檢索!基礎解說(一)
Lucene.Net是一套C#開源全文索引庫,其主要包含了:
· Index : 提供索引的管理與詞組的排序
· Search : 提供查詢相關功能
· Store : 支援資料儲存管理,包括I/O操作
· Util : 共用套件
· Documents : 負責描述索引儲存時的文件結構管理
· QueryParsers : 提供查詢語法
· Analysis : 負責分析內容
要達到高效能的全文檢索讓機器可以明白我們的語言,最重要的關鍵就是"分詞器"了。
試想一下這一句話你會如何拆分成一段一段的關鍵字呢?
"一天一蘋果,醫生遠離我"
還有英文版本
"An apple a day, doctor keep me away."
中文版本的拆分:
"一天"、"一"、"蘋果"、"醫生"、"遠離"、"我"
英文版本的拆分:
"apple"、"day"、"doctor"、"keep"、"me"、"away"
有沒有注意到不同語系所分析出來的關鍵字有一點不一樣呢?
而在Lucene中分詞的工作會交給Analysis來完成,
不過我們可以依照不同的語系去選擇想使用的分詞器(Analyzer)!

首先簡單說明一下Lucene的實作流程
1. 確認主要搜尋的語系來決定使用的分詞器(analyzer)
2. 建立Document依照analyzer匯入資料
(前置完成)
3. 建立IndexSearcher導入準備好的Document
4. 建立Parser來分析SearchValue
5. 使用IndexSearcher分析Parser取得結果(Hits)
*本專案使用的是Lucene.Net 3.0.3*
接下來我們來建立一個提供查詢使用的Document。

       
 // 取得或建立Lucene文件資料夾
        if (!File.Exists(_dir.FullName))
        {
            System.IO.Directory.CreateDirectory(_dir.FullName);
        }
        // Asp.Net Core需要於Nuget安裝System.Configuration.ConfigurationManager提供用戶端應用程式的組態檔存取
        Lucene.Net.Store.Directory directory = FSDirectory.Open(_dir);
        // 選擇分詞器
        var analyzer = new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_CURRENT);
        // 資料來源
        var repository = new Repository();
        // 依照指定的文件結構來建立
        var indexWriter = new IndexWriter(directory, analyzer, true, IndexWriter.MaxFieldLength.LIMITED);
        foreach (var index in repository)
        {
            var document = new Document();
            document.Add(new Field("Id", index.Id.ToString(), Field.Store.YES, Field.Index.NO));
            document.Add(new Field("Name", index.Name, Field.Store.YES, Field.Index.ANALYZED));
            document.Add(new Field("Description", index.Description, Field.Store.NO, Field.Index.ANALYZED));
            indexWriter.AddDocument(document);
        }
        indexWriter.Optimize();
        indexWriter.Commit();
        indexWriter.Dispose();


如此一來我們就建立好Lucene的基本配備囉!
其中analyzer的部分我們使用Lucene.Net預設,
要特別注意的是,其處理中文語系的能力非常之爛!
之後再寫一篇文章深入探討。
再來值得一提的是
       
document.Add(new Field("Id", index.Id.ToString(), Field.Store.YES, Field.Index.NO));

前兩個參數就是Key跟Value,可以簡單理解為欄位與其內容。
後面兩個參數是重點!
Store: 代表是否儲存這個Key的Value
例如在google打上台南美食會搜索出許多不同的文章連結,
不過google給你的資料中最重要的不是文章內容(Description),
而是哪一篇文章(Name)與台南美食最有關係。
假如今天我只要回傳一個列表而不用提示文章中有哪些內容,
那麼我就可以選擇給"Description" Field.Store.No來節省空間。
Index:
· NO - 不加入索引,這個內容只需要隨著結果出爐,不需要在查詢的時候被考慮。
· ANALYZED、NOT_ANALYZED - 是否使用分詞
· NO_NORMS - 關閉權重功能
或許許多人會對權重功能(NORMS)感到疑惑,
簡單的舉個例子
{ Id=1, Key="蘋果", Value="一天一蘋果,醫生遠離我。"}
{ Id=2, Key="橘子", Value="醫生給娜美最珍貴的寶藏。"}
{ Id=3, Key="梨子", Value="我是梨子,比蘋果蘋果好吃多囉!"}
當我搜尋"蘋果"的時候結果會是
{ Id=1, MatchKey=1, MatchValue=1, Score=(1*5) + (1*2) = 7}
{ Id=3, MatchKey=0, MatchValue=1, Score=(0*5) + (2*2) = 4}
有發現了嗎?
雖然同樣都對中兩個結果但是Id 1的資料Key值中有包含關鍵字,
因此得到較高的分數排在Id 3前方
準備好Document了,我們可以開始來實際使用看看囉!

       
// 決定所要搜索的欄位
        var parser = new QueryParser(Lucene.Net.Util.Version.LUCENE_CURRENT, "Description", analyzer).Parse(searchValue);
        // 提供剛剛建立的Document
        var indexSearcher = new IndexSearcher(directory);
        // 搜尋取出結果的數量
        var queryLimit = 20;
        // 開始搜尋!
        var hits = indexSearcher.Search(parser, queryLimit);
        if (!hits.ScoreDocs.Any())
        {
            Console.WriteLine("查無相關結果。");
            return;
        }
        Document doc;
        foreach (var hit in hits.ScoreDocs)
        {
            doc = indexSearcher.Doc(hit.Doc);
            Console.WriteLine("Score :" + hit.Score + ", Id :" + doc.Get("Id") + ", Name :" + doc.Get("Name") + ", Description :" + doc.Get("Description"));
        }


最後的結果(Hits),是需要再回到Document去撈出對應的資料喔!
是不是非常簡單呢?
筆者寫了一個簡單的範例在GitHub上,秉持著追求新技術的心使用了.Net 6,還請各位大大多多包涵。
有中英文兩種Repository,只需要在上方的DI注入切換就可以囉!
GitHub連結: https://github.com/g13579112000/Lucene
筆者第一次撰寫這種教學文章,有哪邊錯誤的非常歡迎一起來討論指教。
之後有機會再撰寫Lucene更深入的應用方面,
例如權重的分配與分詞器的選擇與使用。
感謝您的閱讀。


參考文獻:
1.黑暗大大的全文檢索筆記: https://blog.darkthread.net/blog/lucene-net-notes-1/
2.使用.Net實現全文檢索: https://blog.csdn.net/huwei2003/article/details/53408388
3.伊凡的部落格: http://irfen.me/5-lucene4-9-learning-record-lucene-analysis-tokenizer/
4.純淨天空代碼範例: https://vimsky.com/zh-tw/examples/detail/csharp-ex-Lucene.Net.Documents-Document---class.html
More...
梨子, 2022/2/24 下午 08:23:46
SU 的新規格 RFP
1. .Net Core 5.0 使用.
2. 可切換後, 適用於 MsSQL, MySql, Oracle
3. 預設所有 SQL 執行時要經過 SQL Injection 檢查.
(移除 "CheckDangerSQL", 併入 IsSqlInjection) 

預設會把 CR 和 LF 換成 空白,以免 sql injection 檢查發生錯誤, 有參數可以控制這個行為。sql 和 資料應該要分開,sql 中的 CR 和 LF 被換成空白應該不會有問題。

4. 不要再使用 SqlStr, 改用 SqlValue (避免誤用, SqlStr 有一個問題, 若是忘了加上 '' 會有可能造成 sql injection)

5. ORM 的 Class Name, 若遇到全大寫的字節, 要先轉小寫, 再把第一個字母變大寫.

6. CopyPropertiesTo, CopyTo.. 
   SetValue 時, 若發生錯誤, 要顯示錯誤欄位名稱. (Tmi 的版本, ObjUtil.cs)

7. CopyFromDataRow: 
   string 自動轉 DateTime
   string 自動轉  int, long, decimal..

8. Criteria 的 In 和 operator (|) 要接 list 做為參數, 不要再直接用字串做參數.

9. OrderBy 增加 by column 且可以多個串接

10. Update 時可以用 sql 語法 (參考聖宜的  GetSetFieldWithExpression)

11. 檢查 SQL Injection 的方法改為先把 \r 和 \n 用空白取代,再檢查, 再取代參數。

12. DtFromSql 和 ExecuteSql 傳入 connection 和 transaction 的版本先刪除,未來有需要再增加。 
More...
Bike, 2021/10/18 下午 04:29:15
試題
試說明以下程式碼的功用, 以及可改進的部份.


        string EndDate = Request["EndDate"];

        DataTable qtyControls = U2.SQL.DTFromSQL("Select YA00, PD00 from QtyControl Where EndDate > '" + EndDate + "' and SoldQty >= InitQty");

        var values = qtyControls.AsEnumerable().Select(r => "('" + r.Field<string>("YA00") + "','" + r.Field<string>("PD00") + "')").ToList();

        var sqls = new List<string>();
        sqls.Add("Delete StopSaleYAP;");

        int start = 0;        
        while(start < values.Count)
        {
            var end = start + 999;
            if(end > values.Count - 1)
            {
                end = values.Count;
            }

            sqls.Add("insert into StopSaleYAP(YA00, PD00) Values" + string.Join(",", values.GetRange(start, end)) + ";");

            start = end + 1;
        }

        U2.SQL.ExecuteSQL(string.Join("\r\n", sqls));


        public static bool IsErrorOrder(Order.Input.CheckValidOrder dto)
        {
            if (dto.OrderNos == null || dto.OrderNos.Count == 0)
            {
                return false;
            }

            var orderCount = dto.OrderNos.Count();
            var orders = NpreoOrderMain.GetList(dto.OrderNos);
            if (orders.Count != orderCount || !dto.OrderNos.Any(x => orders.Select(o => o.Order_No).Contains(x)))
            {
                return true;
            }
            return false;
        }


        var fu = Request.Files[0];
        fu.SaveAs(Server.MapPath("UploadFiles/") + fu.FileName);


--

基本題:

1. 對 Linq 熟嗎.

2. 對 ASP.Net 的 Cache  熟悉嗎.

3. 用過什麼 ORM, 試說明優缺點.

4. 試說明 MVC 的架構.

資安相關問題:

1. 試說明 SQL Injection

2. 試說明 Cross Site Injection.

3. 上傳檔案要注意的事項.

4. 試說明 cookie 的安全設定 ? same site, secure, http only.


前端相關加分題:

1. jQuery 或 Vue 熟悉嗎 ?

2. 試說明 RWD

3. 試說明 bootstrap

進階問題:

1. 試說明 Reflection

2. 試說明 Dependency Injection

3.  試說明 singleton vs static

4. 試單有兩個欄位 Id, Status (付款待確認: 1.1;  已付款: 2,  訂單已出貨: 3; 訂單取消中: 5; )
狀態 1.1 和 狀態 2 的訂單可取消,取消後改為狀態 5

客人要取消訂單,訂單編號為 123, 試說明程式執行的過程。
More...
Bike, 2020/10/24 上午 10:24:51
處理 json 的一些問題
1. ExpandoObject 用 string 為 key 取值時, 必需轉換為 IDictionary 物件.

2. int 類別的欄位, 傳入的 json 中, 相對應的欄位, 不能為 null.

 
More...
Bike, 2020/10/20 上午 08:12:20
GetCachedDTWithDateFields
如果有開始日期和結束日期的欄位, 暫存有些要注意的. 內容後補.
More...
Bike, 2019/5/30 下午 05:21:21
bootstrap-formhelpers intlTelInput 套件注意的問題
A下拉霸
 <div class="col-md-6">
                                        <label for="contact:fromlan">Source Language <span class="red">*</span></label>
                                        <div class="bfh-selectbox" data-name="From_Language_Id" id="FromLanItemParent">
                                            <!--FromLanItem S-->
                                            <div data-value="{Id}"><img src="assets/images/_smarty/flags/{Image}" alt="{Abbreviation}"> {LanguageName}</div>
                                            <!--FromLanItem E-->
                                        </div>
                                    </div>

自動生成的下拉霸
1 name 要用 data-name=""來設定
2 完全沒有選擇的時候可能會回傳空值

套件來源
http://bootstrapformhelpers.com/select/

B電話號碼
<label for="contact_department">Your Phone Number </label>
                                        <div>
                                            <input id="phone" name="phone" type="tel">

                                        </div>
                                        <div style="display:none">
                                            <input id="PhoneCountry" name="PhoneCountry" type="">
                                        </div>


                                        <script src="/assets/build/js/intlTelInput.js"></script>
                                        <script>
                                            var input = document.querySelector("#phone");
                                            var iti1 = window.intlTelInput(input, {
                                                // allowDropdown: false,
                                                // autoHideDialCode: false,
                                                // autoPlaceholder: "off",
                                                // dropdownContainer: document.body,
                                                // excludeCountries: ["us"],
                                                // formatOnDisplay: false,
                                                // geoIpLookup: function(callback) {
                                                //   $.get("http://ipinfo.io", function() {}, "jsonp").always(function(resp) {
                                                //     var countryCode = (resp && resp.country) ? resp.country : "";
                                                //     callback(countryCode);
                                                //   });
                                                // },
                                                // hiddenInput: "full_number",
                                                // initialCountry: "auto",
                                                // localizedCountries: { 'de': 'Deutschland' },
                                                // nationalMode: false,
                                                // onlyCountries: ['us', 'gb', 'ch', 'ca', 'do'],
                                                placeholderNumberType: "MOBILE",
                                                // preferredCountries: ['cn', 'jp'],
                                                separateDialCode: true,
                                                utilsScript: "/assets/build/js/utils.js",
                                            });
                                            input.addEventListener("countrychange", function () {
                                                $('#PhoneCountry').val(JSON.stringify(iti1.getSelectedCountryData()))
                                                // do something with iti.getSelectedCountryData()
                                            });
                                        </script>

需要用另一個欄位來記錄電話號碼的國家資料 

套件的來源
https://github.com/jackocnr/intl-tel-input
 
More...
sean, 2019/3/6 上午 10:41:03
用 sqlcmd 把查詣結果匯出 csv 檔
sqlcmd -S 192.168.XXX.YYY -d EmailKeeper -U sa -P xxxxxx -Q "Select distinct Email, EncEmail from EmailEnc"  -o "EmailEnc.csv" -h -1 -s,

-h: 不要 header
-1; 不用第一行的 -----------
-s,: 用 "," 來分隔欄位.
More...
Bike, 2018/10/7 下午 09:26:44
合約應備註事項
注意事項 (為避免產出結果和預期有重大差異, 請詳讀以下內容):

1. 若後台有使用 HTML 編輯器, 以 CKEditor 現有功能為準. 編輯器所見內容和前台實際內容可能有差異, 此為無法避免之情況, 請僅慎使用, 建議以文字模式編輯, 以避免跑版.
2. 驗收以 Chrome, IE, Safari, Firefox 結案時間的最新兩個版本為準(IE 目前為 IE Edge 及 IE 11). 手機以前 10 大廠牌兩年內出版的手機為準.
3. Android 手機僅測試 Chrome, IOS 手機僅測試 Safari. 其它手機預設瀏覽器或 APP 內建流覽器不包括在驗收範圍之內.
4. 若需要文件, 除報價有說明外, 應另外計費, 若合約中包括程式檔案說明, 僅限我方建立之程式檔案, 引用之公開套件不另做文件說明.
5. 若客戶要求資安弱點掃瞄, 或通過特別認証, 應另外計費.
6. 本公司盡力維護程式品質, 但無法保証無 Bug, 上線前請完整測試. 若上線後才發現之 Bug, 本公司僅負責修復, 無法提供額外賠償.
7. 主機代管限制
    圖檔以經 Cloudfalre 為準. 若需更高品質可代為申請 amazon 的 CDN 服務.
    Email 不保証送達, 若需更高品質可代為申請 amazon 的 SES 服務.
    每月 1000 張訂單為限, 超過後要另外計算費用.
8. 網站代管, 資料備份以一天一次為準, 如需增加頻率, 另外協議後計價.
9. 搜尋建議使用 Google 的 site search(但偶爾會有廣告, 出現機率很小), 若要自行客製, 合約未明確規定時, 以各單元分開搜尋為準, 例如產品及新聞的搜尋結果會分成兩個搜尋結果頁面, 排序為依等定欄位排序, 比對方式為所輸入的文字明確比對.
More...
Bike, 2018/6/20 下午 07:49:31
LINQ 用變數方式讀取欄位

        public void TEST(SEPM.SEPMDataContext oDC)
        {
            //一般 LINQ 寫法, 欄位只能寫死, 如:
            var Q = query.OrderBy(r => r.statusId).ToList();

            //若 OrderBy 的欄位不是固定的

            //方法一:條列
            var orderBy = "XXX";
            if (orderBy == "ownerId")
            {
                Q = Q.OrderBy(r => r.ownerId).ToList();
            }
            else if (orderBy == "endDate")
            {
                Q = Q.OrderBy(r => r.endDate).ToList();
            }

            //方法二:
            Q = Q.OrderBy(r => GetPropertyValue(r, orderBy)).ToList();
        }

        private object GetPropertyValue(object obj, string property)
        {
            System.Reflection.PropertyInfo propertyInfo = obj.GetType().GetProperty(property);
            return propertyInfo.GetValue(obj, null);
        }



參考:http://coderemind.blogspot.tw/2013/10/linq.html
More...
Reiko, 2018/4/20 上午 09:14:26
SQL 變更欄位不允許儲存
修改欄位設定時,出現需要刪除資料表(drop table)再建立資料表(create table)才能修改時,
於 [工具] > [選項] > [設計工具]
清除防止儲存需要重新建立資料表的變更] 核取方塊,即可。
如下圖


參考網址:https://support.microsoft.com/zh-tw/help/956176/error-message-when-you-try-to-save-a-table-in-sql-server-saving-change
 
More...
choco, 2017/12/27 下午 01:49:41
|< 1234 >|
頁數 2 / 4 上一頁 下一頁
~ Uwinfo ~