關于Query的學習。
主要使用TermQuery和BooleanQuery,它們是最最基礎的Query。
我感覺Query的靈活性太大了,這就使得它那么地具有魅力。
當用戶提交了檢索關鍵字以后,首先就是要根據這個關鍵字進行分析,因為不同的用戶提交的關鍵詞具有不同的特點,所以使用不同方式來構造Query是極其關鍵的,從而使提供的檢索服務最大程度地滿足用戶的意愿。
先看看Query抽象類的繼承關系,如圖所示:
最簡單最基礎的就是構造一個TermQuery,根據詞條本身直接來構造一個Query,從而進行檢索。
Query類抽象類了進行檢索所具有的共同特征,源代碼實現如下所示:
package org.apache.lucene.search;
import java.io.IOException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.apache.lucene.index.IndexReader;
public abstract class Query implements java.io.Serializable, Cloneable {
// boost是一個非常重要的屬性,它體現了檢索到的Document的重要程度,Lucene默認值為1.0,當然可以自行設置
private float boost = 1.0f;????????????????????
public void setBoost(float b) { boost = b; }
public float getBoost() { return boost; }
public abstract String toString(String field);
public String toString() {
??? return toString("");
}
//??? 一個Query與一個Weight相關
protected Weight createWeight(Searcher searcher) throws IOException {
??? throw new UnsupportedOperationException();
}
public Weight weight(Searcher searcher)
??? throws IOException {
??? Query query = searcher.rewrite(this);
??? Weight weight = query.createWeight(searcher);
??? float sum = weight.sumOfSquaredWeights();
??? float norm = getSimilarity(searcher).queryNorm(sum);
??? weight.normalize(norm);
??? return weight;
}
//??? 重寫一個Query
public Query rewrite(IndexReader reader) throws IOException {
??? return this;
}
//??? 該方法主要是為復雜查詢建立的,通過多個Query的合并來實現,比如,一個BooleanQuery可以是幾個TermQuery的合并
public Query combine(Query[] queries) {
??? HashSet uniques = new HashSet();
??? for (int i = 0; i < queries.length; i++) {
????? Query query = queries[i];
????? BooleanClause[] clauses = null;
????? //?? 是否需要將一個Query分割成多個查詢子句的標志
????? boolean splittable = (query instanceof BooleanQuery);???
// 可見,這里是對BooleanQuery而言的
????? if(splittable){
??????? BooleanQuery bq = (BooleanQuery) query;
??????? splittable = bq.isCoordDisabled();
??????? clauses = bq.getClauses();
??????? for (int j = 0; splittable && j < clauses.length; j++) {
????????? splittable = (clauses[j].getOccur() == BooleanClause.Occur.SHOULD);
??????? }
????? }
????? if(splittable){
??????? for (int j = 0; j < clauses.length; j++) {
????????? uniques.add(clauses[j].getQuery());
??????? }
????? } else {
??????? uniques.add(query);
????? }
??? }
???
// 如果只有一個查詢子句,直接返回
??? if(uniques.size() == 1){
??????? return (Query)uniques.iterator().next();
??? }
??? Iterator it = uniques.iterator();
??? BooleanQuery result = new BooleanQuery(true);
??? while (it.hasNext())
????? result.add((Query) it.next(), BooleanClause.Occur.SHOULD);
??? return result;
}
//??? 從構造的Query中提取出與該查詢關聯的詞條,即用戶鍵入的檢索關鍵字構造的詞條
public void extractTerms(Set terms) {
??? // needs to be implemented by query subclasses
??? throw new UnsupportedOperationException();
}
//??? 合并多個BooleanQuery,構造復雜查詢
public static Query mergeBooleanQueries(Query[] queries) {
??? HashSet allClauses = new HashSet();
??? for (int i = 0; i < queries.length; i++) {
????? BooleanClause[] clauses = ((BooleanQuery)queries[i]).getClauses();
????? for (int j = 0; j < clauses.length; j++) {
??????? allClauses.add(clauses[j]);
????? }
??? }
??? boolean coordDisabled =
????? queries.length==0? false : ((BooleanQuery)queries[0]).isCoordDisabled();
??? BooleanQuery result = new BooleanQuery(coordDisabled);
??? Iterator i = allClauses.iterator();
??? while (i.hasNext()) {
????? result.add((BooleanClause)i.next());
??? }
??? return result;
}
//??? 獲取與查詢相關的Similarity(相似度)實例
public Similarity getSimilarity(Searcher searcher) {
??? return searcher.getSimilarity();
}
//??? Query是支持克隆的
public Object clone() {
??? try {
????? return (Query)super.clone();
??? } catch (CloneNotSupportedException e) {
????? throw new RuntimeException("Clone not supported: " + e.getMessage());
??? }
}
}
上面出現了BooleanQuery,從字面可以了解到這種Query是基于邏輯運算的。BooleanQuery可以是多個子句的邏輯運算。從BooleanQuery的代碼中可以看到,它支持子句的最大數量為1024:
private static int maxClauseCount = 1024;
但是,并非越多子句參與邏輯運算就越好,這里有個效率問題,因為多個子句的合并,要通過各自的Query之后,然后再進行這種邏輯運算,有時時間開銷是不可取的。
BooleanClause是在一個BooleanQuery中子句。該類中定義了一個靜態最終內部類Occur定義了BooleanQuery的運算符:
??? public static final Occur MUST = new Occur("MUST");???
// 與運算
??? public static final Occur SHOULD = new Occur("SHOULD");???
// 或運算
??? public static final Occur MUST_NOT = new Occur("MUST_NOT");???
// 非運算
可以通過上面三個算子對Query進行合并,實現復雜的查詢操作。
編寫一個例子,通過構造三個TermQuery,將他們添加(add)到一個BooleanQuery查詢中,使用MUST與運算,如下所示:
package org.apache.lucene.shirdrn.main;
import java.io.IOException;
import java.util.Date;
import java.util.Iterator;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Hit;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
public class BloeanQuerySearcher {
?? public static void main(String[] args) {
???
??? String indexPath = "E:\\Lucene\\myindex";
??? try {
???? IndexSearcher searcher = new IndexSearcher(indexPath);
????
???? String keywordA = "的";
???? Term termA = new Term("contents",keywordA);
???? Query tQueryA = new TermQuery(termA);
????
???? String keywordB = "是";
???? Term termB = new Term("contents",keywordB);
???? Query tQueryB = new TermQuery(termB);
????
???? String keywordC = "在";
???? Term termC = new Term("contents",keywordC);
???? Query tQueryC = new TermQuery(termC);
????
???? Term[] arrayTerm = new Term[]{null,null,null};
???? arrayTerm[0] = termA;
???? arrayTerm[1] = termB;
???? arrayTerm[2] = termC;
????
???? BooleanQuery bQuery = new BooleanQuery();
???? bQuery.add(tQueryA,BooleanClause.Occur.MUST);
???? bQuery.add(tQueryB,BooleanClause.Occur.MUST);
???? bQuery.add(tQueryC,BooleanClause.Occur.MUST);
????
???? Date startTime = new Date();
???? Hits hits = searcher.search(bQuery);
???? Iterator it = hits.iterator();
???? System.out.println("********************************************************************");
???? while(it.hasNext()){
????? Hit hit = (Hit)it.next();
????? System.out.println("Hit的ID 為 : "+hit.getId());
????? System.out.println("Hit的score 為 : "+hit.getScore());
????? System.out.println("Hit的boost 為 : "+hit.getBoost());
????? System.out.println("Hit的toString 為 : "+hit.toString());
????? System.out.println("Hit的Dcoment 為 : "+hit.getDocument());
????? System.out.println("Hit的Dcoment 的 Fields 為 : "+hit.getDocument().getFields());
????? for(int i=0;i<hit.getDocument().getFields().size();i++){
?????? Field field = (Field)hit.getDocument().getFields().get(i);
?????? System.out.println("????? -------------------------------------------------------------");
?????? System.out.println("????? Field的Name為 : "+field.name());
?????? System.out.println("????? Field的stringValue為 : "+field.stringValue());
????? }
????? System.out.println("********************************************************************");
???? }
???? System.out.println("包含3個詞條的Hits長度為 : "+hits.length());
???? for(int i=0;i<searcher.docFreqs(arrayTerm).length;i++){
????? System.out.println("包含3個詞條的Document的數量為 : "+searcher.docFreqs(arrayTerm)[i]);
???? }
???? Date finishTime = new Date();
???? long timeOfSearch = finishTime.getTime() - startTime.getTime();
???? System.out.println("本次搜索所用的時間為 "+timeOfSearch+" ms");
??? } catch (CorruptIndexException e) {
???? e.printStackTrace();
??? } catch (IOException e) {
???? e.printStackTrace();
??? }
?? }
}
?
下面對各種邏輯運算的組合看一下效果:
1、第一種組合:
???? bQuery.add(tQueryA,BooleanClause.Occur.
MUST
);
???? bQuery.add(tQueryB,BooleanClause.Occur.
MUST
);
???? bQuery.add(tQueryC,BooleanClause.Occur.
MUST
);
查詢結果即是,同時包含三個詞條(詞條的文本內容為:的、在、是)的所有文檔被檢索出來。可以猜想一下,上面撒個詞條:“的”、“是”、“在”在漢語中應該是出現頻率非常高的,預期結果應該會查詢出來較多的符合下面與運算條件的結果:
???? bQuery.add(tQueryA,BooleanClause.Occur.MUST);
???? bQuery.add(tQueryB,BooleanClause.Occur.MUST);
???? bQuery.add(tQueryC,BooleanClause.Occur.MUST);
實際運行結果如下所示:
********************************************************************
Hit的ID 為 : 12
Hit的score 為 : 0.63582987
Hit的boost 為 : 1.0
Hit的toString 為 : Hit<
org.apache.lucene.search.Hits@ab50cd
[0] resolved>
Hit的Dcoment 為 : Document<stored/uncompressed,indexed<path:E:\Lucene\txt1\mytxt\CustomKeyInfo.txt> stored/uncompressed,indexed<modified:200406041814>>
Hit的Dcoment 的 Fields 為 : [stored/uncompressed,indexed<path:E:\Lucene\txt1\mytxt\CustomKeyInfo.txt>, stored/uncompressed,indexed<modified:200406041814>]
????? -------------------------------------------------------------
????? Field的Name為 : path
????? Field的stringValue為 : E:\Lucene\txt1\mytxt\CustomKeyInfo.txt
????? -------------------------------------------------------------
????? Field的Name為 : modified
????? Field的stringValue為 : 200406041814
********************************************************************
Hit的ID 為 : 24
Hit的score 為 : 0.6183762
Hit的boost 為 : 1.0
Hit的toString 為 : Hit<
org.apache.lucene.search.Hits@ab50cd
[1] resolved>
Hit的Dcoment 為 : Document<stored/uncompressed,indexed<path:E:\Lucene\txt1\mytxt\FAQ.txt> stored/uncompressed,indexed<modified:200604130754>>
Hit的Dcoment 的 Fields 為 : [stored/uncompressed,indexed<path:E:\Lucene\txt1\mytxt\FAQ.txt>, stored/uncompressed,indexed<modified:200604130754>]
????? -------------------------------------------------------------
????? Field的Name為 : path
????? Field的stringValue為 : E:\Lucene\txt1\mytxt\FAQ.txt
????? -------------------------------------------------------------
????? Field的Name為 : modified
????? Field的stringValue為 : 200604130754
********************************************************************
Hit的ID 為 : 63
Hit的score 為 : 0.53687334
Hit的boost 為 : 1.0
Hit的toString 為 : Hit<
org.apache.lucene.search.Hits@ab50cd
[2] resolved>
Hit的Dcoment 為 : Document<stored/uncompressed,indexed<path:E:\Lucene\txt1\疑問即時記錄.txt> stored/uncompressed,indexed<modified:200711141408>>
Hit的Dcoment 的 Fields 為 : [stored/uncompressed,indexed<path:E:\Lucene\txt1\疑問即時記錄.txt>, stored/uncompressed,indexed<modified:200711141408>]
????? -------------------------------------------------------------
????? Field的Name為 : path
????? Field的stringValue為 : E:\Lucene\txt1\疑問即時記錄.txt
????? -------------------------------------------------------------
????? Field的Name為 : modified
????? Field的stringValue為 : 200711141408
********************************************************************
Hit的ID 為 : 60
Hit的score 為 : 0.50429535
Hit的boost 為 : 1.0
Hit的toString 為 : Hit<
org.apache.lucene.search.Hits@ab50cd
[3] resolved>
Hit的Dcoment 為 : Document<stored/uncompressed,indexed<path:E:\Lucene\txt1\mytxt\貓吉又有個忙,需要大家幫忙一下.txt> stored/uncompressed,indexed<modified:200706161112>>
Hit的Dcoment 的 Fields 為 : [stored/uncompressed,indexed<path:E:\Lucene\txt1\mytxt\貓吉又有個忙,需要大家幫忙一下.txt>, stored/uncompressed,indexed<modified:200706161112>]
????? -------------------------------------------------------------
????? Field的Name為 : path
????? Field的stringValue為 : E:\Lucene\txt1\mytxt\貓吉又有個忙,需要大家幫忙一下.txt
????? -------------------------------------------------------------
????? Field的Name為 : modified
????? Field的stringValue為 : 200706161112
********************************************************************
Hit的ID 為 : 46
Hit的score 為 : 0.4266696
Hit的boost 為 : 1.0
Hit的toString 為 : Hit<
org.apache.lucene.search.Hits@ab50cd
[4] resolved>
Hit的Dcoment 為 : Document<stored/uncompressed,indexed<path:E:\Lucene\txt1\mytxt\使用技巧集萃.txt> stored/uncompressed,indexed<modified:200511210413>>
Hit的Dcoment 的 Fields 為 : [stored/uncompressed,indexed<path:E:\Lucene\txt1\mytxt\使用技巧集萃.txt>, stored/uncompressed,indexed<modified:200511210413>]
????? -------------------------------------------------------------
????? Field的Name為 : path
????? Field的stringValue為 : E:\Lucene\txt1\mytxt\使用技巧集萃.txt
????? -------------------------------------------------------------
????? Field的Name為 : modified
????? Field的stringValue為 : 200511210413
********************************************************************
Hit的ID 為 : 56
Hit的score 為 : 0.4056765
Hit的boost 為 : 1.0
Hit的toString 為 : Hit<
org.apache.lucene.search.Hits@ab50cd
[5] resolved>
Hit的Dcoment 為 : Document<stored/uncompressed,indexed<path:E:\Lucene\txt1\mytxt\新1建 文本文檔.txt> stored/uncompressed,indexed<modified:200710311142>>
Hit的Dcoment 的 Fields 為 : [stored/uncompressed,indexed<path:E:\Lucene\txt1\mytxt\新1建 文本文檔.txt>, stored/uncompressed,indexed<modified:200710311142>]
????? -------------------------------------------------------------
????? Field的Name為 : path
????? Field的stringValue為 : E:\Lucene\txt1\mytxt\新1建 文本文檔.txt
????? -------------------------------------------------------------
????? Field的Name為 : modified
????? Field的stringValue為 : 200710311142
********************************************************************
Hit的ID 為 : 41
Hit的score 為 : 0.3852732
Hit的boost 為 : 1.0
Hit的toString 為 : Hit<
org.apache.lucene.search.Hits@ab50cd
[6] resolved>
Hit的Dcoment 為 : Document<stored/uncompressed,indexed<path:E:\Lucene\txt1\mytxt\Update.txt> stored/uncompressed,indexed<modified:200707050028>>
Hit的Dcoment 的 Fields 為 : [stored/uncompressed,indexed<path:E:\Lucene\txt1\mytxt\Update.txt>, stored/uncompressed,indexed<modified:200707050028>]
????? -------------------------------------------------------------
????? Field的Name為 : path
????? Field的stringValue為 : E:\Lucene\txt1\mytxt\Update.txt
????? -------------------------------------------------------------
????? Field的Name為 : modified
????? Field的stringValue為 : 200707050028
********************************************************************
Hit的ID 為 : 37
Hit的score 為 : 0.35885736
Hit的boost 為 : 1.0
Hit的toString 為 : Hit<
org.apache.lucene.search.Hits@ab50cd
[7] resolved>
Hit的Dcoment 為 : Document<stored/uncompressed,indexed<path:E:\Lucene\txt1\mytxt\readme.txt> stored/uncompressed,indexed<modified:200803101314>>
Hit的Dcoment 的 Fields 為 : [stored/uncompressed,indexed<path:E:\Lucene\txt1\mytxt\readme.txt>, stored/uncompressed,indexed<modified:200803101314>]
????? -------------------------------------------------------------
????? Field的Name為 : path
????? Field的stringValue為 : E:\Lucene\txt1\mytxt\readme.txt
????? -------------------------------------------------------------
????? Field的Name為 : modified
????? Field的stringValue為 : 200803101314
********************************************************************
Hit的ID 為 : 48
Hit的score 為 : 0.35885736
Hit的boost 為 : 1.0
Hit的toString 為 : Hit<
org.apache.lucene.search.Hits@ab50cd
[8] resolved>
Hit的Dcoment 為 : Document<stored/uncompressed,indexed<path:E:\Lucene\txt1\mytxt\劍心補丁使用說明(readme).txt> stored/uncompressed,indexed<modified:200803101357>>
Hit的Dcoment 的 Fields 為 : [stored/uncompressed,indexed<path:E:\Lucene\txt1\mytxt\劍心補丁使用說明(readme).txt>, stored/uncompressed,indexed<modified:200803101357>]
????? -------------------------------------------------------------
????? Field的Name為 : path
????? Field的stringValue為 : E:\Lucene\txt1\mytxt\劍心補丁使用說明(readme).txt
????? -------------------------------------------------------------
????? Field的Name為 : modified
????? Field的stringValue為 : 200803101357
********************************************************************
Hit的ID 為 : 47
Hit的score 為 : 0.32808846
Hit的boost 為 : 1.0
Hit的toString 為 : Hit<
org.apache.lucene.search.Hits@ab50cd
[9] resolved>
Hit的Dcoment 為 : Document<stored/uncompressed,indexed<path:E:\Lucene\txt1\mytxt\關系記錄.txt> stored/uncompressed,indexed<modified:200802201145>>
Hit的Dcoment 的 Fields 為 : [stored/uncompressed,indexed<path:E:\Lucene\txt1\mytxt\關系記錄.txt>, stored/uncompressed,indexed<modified:200802201145>]
????? -------------------------------------------------------------
????? Field的Name為 : path
????? Field的stringValue為 : E:\Lucene\txt1\mytxt\關系記錄.txt
????? -------------------------------------------------------------
????? Field的Name為 : modified
????? Field的stringValue為 : 200802201145
********************************************************************
包含3個詞條的Hits長度為 : 10
包含3個詞條的Document的數量為 : 23
包含3個詞條的Document的數量為 : 12
包含3個詞條的Document的數量為 : 14
本次搜索所用的時間為 203 ms
從上面測試可見,查詢的記過具有10項,應該符合我們預期的假設的。
2、第二種組合:
???? bQuery.add(tQueryA,BooleanClause.Occur.
MUST_NOT
);
???? bQuery.add(tQueryB,BooleanClause.Occur.
MUST
);
???? bQuery.add(tQueryC,BooleanClause.Occur.
MUST
);
?
即,把不包含詞條“的”,但是同時包含詞條“是”和“在”,查詢出來的結果應該不會太多,中文的文章中“的”出現的頻率很高很高,上面指定了MUST_NOT,非邏輯運算符,結果如下所示:
********************************************************************
Hit的ID 為 : 54
Hit的score 為 : 0.22303896
Hit的boost 為 : 1.0
Hit的toString 為 : Hit<
org.apache.lucene.search.Hits@ab50cd
[0] resolved>
Hit的Dcoment 為 : Document<stored/uncompressed,indexed<path:E:\Lucene\txt1\mytxt\指定時間內關閉網頁.txt> stored/uncompressed,indexed<modified:200111200742>>
Hit的Dcoment 的 Fields 為 : [stored/uncompressed,indexed<path:E:\Lucene\txt1\mytxt\指定時間內關閉網頁.txt>, stored/uncompressed,indexed<modified:200111200742>]
????? -------------------------------------------------------------
????? Field的Name為 : path
????? Field的stringValue為 : E:\Lucene\txt1\mytxt\指定時間內關閉網頁.txt
????? -------------------------------------------------------------
????? Field的Name為 : modified
????? Field的stringValue為 : 200111200742
********************************************************************
3個詞條的Hits長度為 : 1
包含3個詞條的Document的數量為 : 23
包含3個詞條的Document的數量為 : 12
包含3個詞條的Document的數量為 : 14
本次搜索所用的時間為 140 ms
符合查詢條件的只有一項,只有記事本文件E:\Lucene\txt1\mytxt\指定時間內關閉網頁.txt中滿足查詢條件,即該文件中一定沒有詞條“的”出現,但是同時包含詞條“是”和“在”。
3、第三種組合:
???? bQuery.add(tQueryA,BooleanClause.Occur.
SHOULD
);
???? bQuery.add(tQueryB,BooleanClause.Occur.
SHOULD
);
???? bQuery.add(tQueryC,BooleanClause.Occur.
SHOULD
);
即或操作,可想而知,滿足條件的結果項應該是最多的(我的測試是24項)。
4、第四種組合:
???? bQuery.add(tQueryA,BooleanClause.Occur.
MUST_NOT
);
???? bQuery.add(tQueryB,BooleanClause.Occur.
MUST_NOT
);
???? bQuery.add(tQueryC,BooleanClause.Occur.
MUST_NOT
);
不包含三個詞條的查詢部結果。如果是通常的文本,文本信息量較大,如果同時不包含“的”、“是”、“在”三個詞條,結果是可想而知的,幾乎檢索不出來任何符合這一條件的結果集。
還有一點,用戶通過鍵入關鍵字進行檢索,不會有這樣的用戶:不想獲取與自己鍵入關鍵字匹配的結果呢,其實這種組合沒有意義的。
我的測試為:
********************************************************************
3個詞條的Hits長度為 : 0
包含3個詞條的Document的數量為 : 23
包含3個詞條的Document的數量為 : 12
包含3個詞條的Document的數量為 : 14
本次搜索所用的時間為 94 ms
如果你建立索引的數據源文件類似古代詩詞曲那樣的文本,可能檢索出來的結果會很可觀的。
5、第五種組合:
???? bQuery.add(tQueryA,BooleanClause.Occur.
SHOULD
);
???? bQuery.add(tQueryB,BooleanClause.Occur.
MUST_NOT
);
???? bQuery.add(tQueryC,BooleanClause.Occur.
MUST_NOT
);
???? bQuery.add(tQueryA,BooleanClause.Occur.
MUST
);
???? bQuery.add(tQueryB,BooleanClause.Occur.
MUST_NOT
);
???? bQuery.add(tQueryC,BooleanClause.Occur.
MUST_NOT
);
經過測試,可以得知,上面的這兩種組合檢索得到的結果集是一樣的。也就是說,SHOULD在與MUST_NOT進行組合的時候,其實就是MUST在和MUST_NOT進行組合。
6、第六種組合:
???? bQuery.add(tQueryA,BooleanClause.Occur.
SHOULD
);
???? bQuery.add(tQueryB,BooleanClause.Occur.
MUST
);
???? bQuery.add(tQueryC,BooleanClause.Occur.
MUST
);
其實這種組合與SHOULD沒有任何關系了,相當于下面的2個MUST的組合:
???? bQuery.add(tQueryB,BooleanClause.Occur.
MUST
);
???? bQuery.add(tQueryC,BooleanClause.Occur.
MUST
);
這兩種組合檢索出來的結果集是一樣的。
總結
使用BooleanQuery進行查詢,它工作的機制是這樣的:
1、先對BooleanQuery中的每個子句分別進行查詢,得到多個結果集;
2、對BooleanQuery的各個子句得到的結果集,進行集合的運算(交、并、非)。
最終,集合運算的結果就是顯示給用戶的,與用戶查詢條件匹配的記錄。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
